
bin/kernel:     file format elf32-i386


Disassembly of section .text:

c0100000 <kern_entry>:

.text
.globl kern_entry
kern_entry:
    # load pa of boot pgdir
    movl $REALLOC(__boot_pgdir), %eax
c0100000:	b8 00 90 12 00       	mov    $0x129000,%eax
    movl %eax, %cr3
c0100005:	0f 22 d8             	mov    %eax,%cr3

    # enable paging
    movl %cr0, %eax
c0100008:	0f 20 c0             	mov    %cr0,%eax
    orl $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP), %eax
c010000b:	0d 2f 00 05 80       	or     $0x8005002f,%eax
    andl $~(CR0_TS | CR0_EM), %eax
c0100010:	83 e0 f3             	and    $0xfffffff3,%eax
    movl %eax, %cr0
c0100013:	0f 22 c0             	mov    %eax,%cr0

    # update eip
    # now, eip = 0x1.....
    leal next, %eax
c0100016:	8d 05 1e 00 10 c0    	lea    0xc010001e,%eax
    # set eip = KERNBASE + 0x1.....
    jmp *%eax
c010001c:	ff e0                	jmp    *%eax

c010001e <next>:
next:

    # unmap va 0 ~ 4M, it's temporary mapping
    xorl %eax, %eax
c010001e:	31 c0                	xor    %eax,%eax
    movl %eax, __boot_pgdir
c0100020:	a3 00 90 12 c0       	mov    %eax,0xc0129000

    # set ebp, esp
    movl $0x0, %ebp
c0100025:	bd 00 00 00 00       	mov    $0x0,%ebp
    # the kernel stack region is from bootstack -- bootstacktop,
    # the kernel stack size is KSTACKSIZE (8KB)defined in memlayout.h
    movl $bootstacktop, %esp
c010002a:	bc 00 80 12 c0       	mov    $0xc0128000,%esp
    # now kernel stack is ready , call the first C function
    call kern_init
c010002f:	e8 02 00 00 00       	call   c0100036 <kern_init>

c0100034 <spin>:

# should never get here
spin:
    jmp spin
c0100034:	eb fe                	jmp    c0100034 <spin>

c0100036 <kern_init>:
void grade_backtrace(void);
static void lab1_switch_test(void);


    int
kern_init(void) {
c0100036:	55                   	push   %ebp
c0100037:	89 e5                	mov    %esp,%ebp
c0100039:	83 ec 28             	sub    $0x28,%esp
    extern char edata[], end[]; //声明外部变量 edata 和 end
    memset(edata, 0, end - edata); // 将数据段清零
c010003c:	b8 b4 e1 12 c0       	mov    $0xc012e1b4,%eax
c0100041:	2d 00 b0 12 c0       	sub    $0xc012b000,%eax
c0100046:	89 44 24 08          	mov    %eax,0x8(%esp)
c010004a:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0100051:	00 
c0100052:	c7 04 24 00 b0 12 c0 	movl   $0xc012b000,(%esp)
c0100059:	e8 86 9e 00 00       	call   c0109ee4 <memset>

    cons_init();                // init the console 初始化控制台
c010005e:	e8 54 15 00 00       	call   c01015b7 <cons_init>

    const char *message = "(THU.CST) os is loading ...";
c0100063:	c7 45 f4 80 a0 10 c0 	movl   $0xc010a080,-0xc(%ebp)
    cprintf("%s\n\n", message);// 将消息输出到控制台
c010006a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010006d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100071:	c7 04 24 9c a0 10 c0 	movl   $0xc010a09c,(%esp)
c0100078:	e8 fb 02 00 00       	call   c0100378 <cprintf>

    print_kerninfo();// 输出内核信息的函数
c010007d:	e8 19 08 00 00       	call   c010089b <print_kerninfo>

    grade_backtrace(); //调用回溯函数，通常用于调试，显示函数调用栈。
c0100082:	e8 a7 00 00 00       	call   c010012e <grade_backtrace>

    pmm_init();                 // init physical memory management初始化物理内存管理
c0100087:	e8 1d 55 00 00       	call   c01055a9 <pmm_init>

    pic_init();                 // init interrupt controller初始化可编程中断控制器
c010008c:	e8 04 1f 00 00       	call   c0101f95 <pic_init>
    idt_init();                 // init interrupt descriptor table初始化中断描述符表
c0100091:	e8 68 20 00 00       	call   c01020fe <idt_init>

    vmm_init();                 // init virtual memory management 初始化虚拟内存管理
c0100096:	e8 5a 7c 00 00       	call   c0107cf5 <vmm_init>
    
    proc_init();                // init process table
c010009b:	e8 3e 90 00 00       	call   c01090de <proc_init>

    ide_init();                 // init ide devices初始化IDE设备
c01000a0:	e8 4c 16 00 00       	call   c01016f1 <ide_init>
    swap_init();                // init swap 初始化交换分区
c01000a5:	e8 44 67 00 00       	call   c01067ee <swap_init>

    clock_init();               // init clock interrupt 初始化时钟中断
c01000aa:	e8 67 0c 00 00       	call   c0100d16 <clock_init>
    intr_enable();              // enable irq interrupt
c01000af:	e8 3f 1e 00 00       	call   c0101ef3 <intr_enable>

    //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test()
    // user/kernel mode switch test
    //lab1_switch_test();
    
    cpu_idle();                 // run idle process 运行空闲进程
c01000b4:	e8 e6 91 00 00       	call   c010929f <cpu_idle>

c01000b9 <grade_backtrace2>:
}

//不进行内联的回溯函数，调用 mon_backtrace 显示当前的调用栈。
void __attribute__((noinline))
grade_backtrace2(int arg0, int arg1, int arg2, int arg3) {
c01000b9:	55                   	push   %ebp
c01000ba:	89 e5                	mov    %esp,%ebp
c01000bc:	83 ec 18             	sub    $0x18,%esp
    mon_backtrace(0, NULL, NULL);
c01000bf:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01000c6:	00 
c01000c7:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01000ce:	00 
c01000cf:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c01000d6:	e8 56 0b 00 00       	call   c0100c31 <mon_backtrace>
}
c01000db:	90                   	nop
c01000dc:	89 ec                	mov    %ebp,%esp
c01000de:	5d                   	pop    %ebp
c01000df:	c3                   	ret    

c01000e0 <grade_backtrace1>:
//不进行内联的回溯函数，传递参数到 grade_backtrace2
void __attribute__((noinline))
grade_backtrace1(int arg0, int arg1) {
c01000e0:	55                   	push   %ebp
c01000e1:	89 e5                	mov    %esp,%ebp
c01000e3:	83 ec 18             	sub    $0x18,%esp
c01000e6:	89 5d fc             	mov    %ebx,-0x4(%ebp)
    grade_backtrace2(arg0, (int)&arg0, arg1, (int)&arg1);
c01000e9:	8d 4d 0c             	lea    0xc(%ebp),%ecx
c01000ec:	8b 55 0c             	mov    0xc(%ebp),%edx
c01000ef:	8d 5d 08             	lea    0x8(%ebp),%ebx
c01000f2:	8b 45 08             	mov    0x8(%ebp),%eax
c01000f5:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c01000f9:	89 54 24 08          	mov    %edx,0x8(%esp)
c01000fd:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c0100101:	89 04 24             	mov    %eax,(%esp)
c0100104:	e8 b0 ff ff ff       	call   c01000b9 <grade_backtrace2>
}
c0100109:	90                   	nop
c010010a:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c010010d:	89 ec                	mov    %ebp,%esp
c010010f:	5d                   	pop    %ebp
c0100110:	c3                   	ret    

c0100111 <grade_backtrace0>:
//不进行内联的回溯函数，传递参数到 grade_backtrace1
void __attribute__((noinline))
grade_backtrace0(int arg0, int arg1, int arg2) {
c0100111:	55                   	push   %ebp
c0100112:	89 e5                	mov    %esp,%ebp
c0100114:	83 ec 18             	sub    $0x18,%esp
    grade_backtrace1(arg0, arg2);
c0100117:	8b 45 10             	mov    0x10(%ebp),%eax
c010011a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010011e:	8b 45 08             	mov    0x8(%ebp),%eax
c0100121:	89 04 24             	mov    %eax,(%esp)
c0100124:	e8 b7 ff ff ff       	call   c01000e0 <grade_backtrace1>
}
c0100129:	90                   	nop
c010012a:	89 ec                	mov    %ebp,%esp
c010012c:	5d                   	pop    %ebp
c010012d:	c3                   	ret    

c010012e <grade_backtrace>:
//触发回溯的起始点，传递初始化函数地址。
void
grade_backtrace(void) {
c010012e:	55                   	push   %ebp
c010012f:	89 e5                	mov    %esp,%ebp
c0100131:	83 ec 18             	sub    $0x18,%esp
    grade_backtrace0(0, (int)kern_init, 0xffff0000);
c0100134:	b8 36 00 10 c0       	mov    $0xc0100036,%eax
c0100139:	c7 44 24 08 00 00 ff 	movl   $0xffff0000,0x8(%esp)
c0100140:	ff 
c0100141:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100145:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c010014c:	e8 c0 ff ff ff       	call   c0100111 <grade_backtrace0>
}
c0100151:	90                   	nop
c0100152:	89 ec                	mov    %ebp,%esp
c0100154:	5d                   	pop    %ebp
c0100155:	c3                   	ret    

c0100156 <lab1_print_cur_status>:
//打印当前的段寄存器状态。
static void
lab1_print_cur_status(void) {
c0100156:	55                   	push   %ebp
c0100157:	89 e5                	mov    %esp,%ebp
c0100159:	83 ec 28             	sub    $0x28,%esp
    static int round = 0;
    uint16_t reg1, reg2, reg3, reg4;
    //嵌入汇编代码，确保编译器不优化这些代码。
    asm volatile (
c010015c:	8c 4d f6             	mov    %cs,-0xa(%ebp)
c010015f:	8c 5d f4             	mov    %ds,-0xc(%ebp)
c0100162:	8c 45 f2             	mov    %es,-0xe(%ebp)
c0100165:	8c 55 f0             	mov    %ss,-0x10(%ebp)
            "mov %%cs, %0;"// 将当前代码段寄存器的值移动到 reg1
            "mov %%ds, %1;"
            "mov %%es, %2;"
            "mov %%ss, %3;"
            : "=m"(reg1), "=m"(reg2), "=m"(reg3), "=m"(reg4));
    cprintf("%d: @ring %d\n", round, reg1 & 3);//打印当前的 round、权限级（ring）和各段寄存器的值。
c0100168:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c010016c:	83 e0 03             	and    $0x3,%eax
c010016f:	89 c2                	mov    %eax,%edx
c0100171:	a1 00 b0 12 c0       	mov    0xc012b000,%eax
c0100176:	89 54 24 08          	mov    %edx,0x8(%esp)
c010017a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010017e:	c7 04 24 a1 a0 10 c0 	movl   $0xc010a0a1,(%esp)
c0100185:	e8 ee 01 00 00       	call   c0100378 <cprintf>
    cprintf("%d:  cs = %x\n", round, reg1);
c010018a:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c010018e:	89 c2                	mov    %eax,%edx
c0100190:	a1 00 b0 12 c0       	mov    0xc012b000,%eax
c0100195:	89 54 24 08          	mov    %edx,0x8(%esp)
c0100199:	89 44 24 04          	mov    %eax,0x4(%esp)
c010019d:	c7 04 24 af a0 10 c0 	movl   $0xc010a0af,(%esp)
c01001a4:	e8 cf 01 00 00       	call   c0100378 <cprintf>
    cprintf("%d:  ds = %x\n", round, reg2);
c01001a9:	0f b7 45 f4          	movzwl -0xc(%ebp),%eax
c01001ad:	89 c2                	mov    %eax,%edx
c01001af:	a1 00 b0 12 c0       	mov    0xc012b000,%eax
c01001b4:	89 54 24 08          	mov    %edx,0x8(%esp)
c01001b8:	89 44 24 04          	mov    %eax,0x4(%esp)
c01001bc:	c7 04 24 bd a0 10 c0 	movl   $0xc010a0bd,(%esp)
c01001c3:	e8 b0 01 00 00       	call   c0100378 <cprintf>
    cprintf("%d:  es = %x\n", round, reg3);
c01001c8:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c01001cc:	89 c2                	mov    %eax,%edx
c01001ce:	a1 00 b0 12 c0       	mov    0xc012b000,%eax
c01001d3:	89 54 24 08          	mov    %edx,0x8(%esp)
c01001d7:	89 44 24 04          	mov    %eax,0x4(%esp)
c01001db:	c7 04 24 cb a0 10 c0 	movl   $0xc010a0cb,(%esp)
c01001e2:	e8 91 01 00 00       	call   c0100378 <cprintf>
    cprintf("%d:  ss = %x\n", round, reg4);
c01001e7:	0f b7 45 f0          	movzwl -0x10(%ebp),%eax
c01001eb:	89 c2                	mov    %eax,%edx
c01001ed:	a1 00 b0 12 c0       	mov    0xc012b000,%eax
c01001f2:	89 54 24 08          	mov    %edx,0x8(%esp)
c01001f6:	89 44 24 04          	mov    %eax,0x4(%esp)
c01001fa:	c7 04 24 d9 a0 10 c0 	movl   $0xc010a0d9,(%esp)
c0100201:	e8 72 01 00 00       	call   c0100378 <cprintf>
    round ++;//将 round 增加1，以便每次调用时记录状态。
c0100206:	a1 00 b0 12 c0       	mov    0xc012b000,%eax
c010020b:	40                   	inc    %eax
c010020c:	a3 00 b0 12 c0       	mov    %eax,0xc012b000
}
c0100211:	90                   	nop
c0100212:	89 ec                	mov    %ebp,%esp
c0100214:	5d                   	pop    %ebp
c0100215:	c3                   	ret    

c0100216 <lab1_switch_to_user>:

static void
lab1_switch_to_user(void) {
c0100216:	55                   	push   %ebp
c0100217:	89 e5                	mov    %esp,%ebp
    // 从内核模式切换到用户模式
    //LAB1 CHALLENGE 1 : TODO
    asm volatile (
c0100219:	83 ec 08             	sub    $0x8,%esp
c010021c:	cd 78                	int    $0x78
c010021e:	89 ec                	mov    %ebp,%esp
	    "int %0 \n"//通过触发一个中断，将控制权转移到内核，切换到用户模式。
	    "movl %%ebp, %%esp"// 将基指针（EBP）值移动到堆栈指针（ESP），恢复堆栈指针。
	    : 
	    : "i"(T_SWITCH_TOU)//T_SWITCH_TOU是一个常量，表示切换到用户态的中断号。传入常量 T_SWITCH_TOU
	);
}
c0100220:	90                   	nop
c0100221:	5d                   	pop    %ebp
c0100222:	c3                   	ret    

c0100223 <lab1_switch_to_kernel>:

static void
lab1_switch_to_kernel(void) {
c0100223:	55                   	push   %ebp
c0100224:	89 e5                	mov    %esp,%ebp
    // 从用户模式切换到内核模式
    //LAB1 CHALLENGE 1 :  TODO
    asm volatile (
c0100226:	cd 79                	int    $0x79
c0100228:	89 ec                	mov    %ebp,%esp
	    "int %0 \n"// 同样触发中断，这里用的是 T_SWITCH_TOK，从用户态切换回内核态。
	    "movl %%ebp, %%esp \n"//恢复堆栈指针
	    : 
	    : "i"(T_SWITCH_TOK)//传入常量 T_SWITCH_TOU
	);
}
c010022a:	90                   	nop
c010022b:	5d                   	pop    %ebp
c010022c:	c3                   	ret    

c010022d <lab1_switch_test>:

//测试用户模式和内核模式切换。
//调用 lab1_print_cur_status 打印当前状态，进行模式切换，然后再次打印状态。
static void
lab1_switch_test(void) {
c010022d:	55                   	push   %ebp
c010022e:	89 e5                	mov    %esp,%ebp
c0100230:	83 ec 18             	sub    $0x18,%esp
    lab1_print_cur_status();
c0100233:	e8 1e ff ff ff       	call   c0100156 <lab1_print_cur_status>
    cprintf("+++ switch to  user  mode +++\n");
c0100238:	c7 04 24 e8 a0 10 c0 	movl   $0xc010a0e8,(%esp)
c010023f:	e8 34 01 00 00       	call   c0100378 <cprintf>
    lab1_switch_to_user();
c0100244:	e8 cd ff ff ff       	call   c0100216 <lab1_switch_to_user>
    lab1_print_cur_status();
c0100249:	e8 08 ff ff ff       	call   c0100156 <lab1_print_cur_status>
    cprintf("+++ switch to kernel mode +++\n");
c010024e:	c7 04 24 08 a1 10 c0 	movl   $0xc010a108,(%esp)
c0100255:	e8 1e 01 00 00       	call   c0100378 <cprintf>
    lab1_switch_to_kernel();
c010025a:	e8 c4 ff ff ff       	call   c0100223 <lab1_switch_to_kernel>
    lab1_print_cur_status();
c010025f:	e8 f2 fe ff ff       	call   c0100156 <lab1_print_cur_status>
}
c0100264:	90                   	nop
c0100265:	89 ec                	mov    %ebp,%esp
c0100267:	5d                   	pop    %ebp
c0100268:	c3                   	ret    

c0100269 <readline>:
 * The readline() function returns the text of the line read. If some errors
 * are happened, NULL is returned. The return value is a global variable,
 * thus it should be copied before it is used.
 * */
char *
readline(const char *prompt) {
c0100269:	55                   	push   %ebp
c010026a:	89 e5                	mov    %esp,%ebp
c010026c:	83 ec 28             	sub    $0x28,%esp
    if (prompt != NULL) {
c010026f:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0100273:	74 13                	je     c0100288 <readline+0x1f>
        cprintf("%s", prompt);
c0100275:	8b 45 08             	mov    0x8(%ebp),%eax
c0100278:	89 44 24 04          	mov    %eax,0x4(%esp)
c010027c:	c7 04 24 27 a1 10 c0 	movl   $0xc010a127,(%esp)
c0100283:	e8 f0 00 00 00       	call   c0100378 <cprintf>
    }
    int i = 0, c;
c0100288:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    while (1) {
        c = getchar();
c010028f:	e8 73 01 00 00       	call   c0100407 <getchar>
c0100294:	89 45 f0             	mov    %eax,-0x10(%ebp)
        if (c < 0) {
c0100297:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010029b:	79 07                	jns    c01002a4 <readline+0x3b>
            return NULL;
c010029d:	b8 00 00 00 00       	mov    $0x0,%eax
c01002a2:	eb 78                	jmp    c010031c <readline+0xb3>
        }
        else if (c >= ' ' && i < BUFSIZE - 1) {
c01002a4:	83 7d f0 1f          	cmpl   $0x1f,-0x10(%ebp)
c01002a8:	7e 28                	jle    c01002d2 <readline+0x69>
c01002aa:	81 7d f4 fe 03 00 00 	cmpl   $0x3fe,-0xc(%ebp)
c01002b1:	7f 1f                	jg     c01002d2 <readline+0x69>
            cputchar(c);
c01002b3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01002b6:	89 04 24             	mov    %eax,(%esp)
c01002b9:	e8 e2 00 00 00       	call   c01003a0 <cputchar>
            buf[i ++] = c;
c01002be:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01002c1:	8d 50 01             	lea    0x1(%eax),%edx
c01002c4:	89 55 f4             	mov    %edx,-0xc(%ebp)
c01002c7:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01002ca:	88 90 20 b0 12 c0    	mov    %dl,-0x3fed4fe0(%eax)
c01002d0:	eb 45                	jmp    c0100317 <readline+0xae>
        }
        else if (c == '\b' && i > 0) {
c01002d2:	83 7d f0 08          	cmpl   $0x8,-0x10(%ebp)
c01002d6:	75 16                	jne    c01002ee <readline+0x85>
c01002d8:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01002dc:	7e 10                	jle    c01002ee <readline+0x85>
            cputchar(c);
c01002de:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01002e1:	89 04 24             	mov    %eax,(%esp)
c01002e4:	e8 b7 00 00 00       	call   c01003a0 <cputchar>
            i --;
c01002e9:	ff 4d f4             	decl   -0xc(%ebp)
c01002ec:	eb 29                	jmp    c0100317 <readline+0xae>
        }
        else if (c == '\n' || c == '\r') {
c01002ee:	83 7d f0 0a          	cmpl   $0xa,-0x10(%ebp)
c01002f2:	74 06                	je     c01002fa <readline+0x91>
c01002f4:	83 7d f0 0d          	cmpl   $0xd,-0x10(%ebp)
c01002f8:	75 95                	jne    c010028f <readline+0x26>
            cputchar(c);
c01002fa:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01002fd:	89 04 24             	mov    %eax,(%esp)
c0100300:	e8 9b 00 00 00       	call   c01003a0 <cputchar>
            buf[i] = '\0';
c0100305:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100308:	05 20 b0 12 c0       	add    $0xc012b020,%eax
c010030d:	c6 00 00             	movb   $0x0,(%eax)
            return buf;
c0100310:	b8 20 b0 12 c0       	mov    $0xc012b020,%eax
c0100315:	eb 05                	jmp    c010031c <readline+0xb3>
        c = getchar();
c0100317:	e9 73 ff ff ff       	jmp    c010028f <readline+0x26>
        }
    }
}
c010031c:	89 ec                	mov    %ebp,%esp
c010031e:	5d                   	pop    %ebp
c010031f:	c3                   	ret    

c0100320 <cputch>:
/* *
 * cputch - writes a single character @c to stdout, and it will
 * increace the value of counter pointed by @cnt.
 * */
static void
cputch(int c, int *cnt) {
c0100320:	55                   	push   %ebp
c0100321:	89 e5                	mov    %esp,%ebp
c0100323:	83 ec 18             	sub    $0x18,%esp
    cons_putc(c);
c0100326:	8b 45 08             	mov    0x8(%ebp),%eax
c0100329:	89 04 24             	mov    %eax,(%esp)
c010032c:	e8 b5 12 00 00       	call   c01015e6 <cons_putc>
    (*cnt) ++;
c0100331:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100334:	8b 00                	mov    (%eax),%eax
c0100336:	8d 50 01             	lea    0x1(%eax),%edx
c0100339:	8b 45 0c             	mov    0xc(%ebp),%eax
c010033c:	89 10                	mov    %edx,(%eax)
}
c010033e:	90                   	nop
c010033f:	89 ec                	mov    %ebp,%esp
c0100341:	5d                   	pop    %ebp
c0100342:	c3                   	ret    

c0100343 <vcprintf>:
 *
 * Call this function if you are already dealing with a va_list.
 * Or you probably want cprintf() instead.
 * */
int
vcprintf(const char *fmt, va_list ap) {
c0100343:	55                   	push   %ebp
c0100344:	89 e5                	mov    %esp,%ebp
c0100346:	83 ec 28             	sub    $0x28,%esp
    int cnt = 0;
c0100349:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    vprintfmt((void*)cputch, &cnt, fmt, ap);
c0100350:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100353:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0100357:	8b 45 08             	mov    0x8(%ebp),%eax
c010035a:	89 44 24 08          	mov    %eax,0x8(%esp)
c010035e:	8d 45 f4             	lea    -0xc(%ebp),%eax
c0100361:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100365:	c7 04 24 20 03 10 c0 	movl   $0xc0100320,(%esp)
c010036c:	e8 c6 92 00 00       	call   c0109637 <vprintfmt>
    return cnt;
c0100371:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0100374:	89 ec                	mov    %ebp,%esp
c0100376:	5d                   	pop    %ebp
c0100377:	c3                   	ret    

c0100378 <cprintf>:
 *
 * The return value is the number of characters which would be
 * written to stdout.
 * */
int
cprintf(const char *fmt, ...) {
c0100378:	55                   	push   %ebp
c0100379:	89 e5                	mov    %esp,%ebp
c010037b:	83 ec 28             	sub    $0x28,%esp
    va_list ap;
    int cnt;
    va_start(ap, fmt);
c010037e:	8d 45 0c             	lea    0xc(%ebp),%eax
c0100381:	89 45 f0             	mov    %eax,-0x10(%ebp)
    cnt = vcprintf(fmt, ap);
c0100384:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0100387:	89 44 24 04          	mov    %eax,0x4(%esp)
c010038b:	8b 45 08             	mov    0x8(%ebp),%eax
c010038e:	89 04 24             	mov    %eax,(%esp)
c0100391:	e8 ad ff ff ff       	call   c0100343 <vcprintf>
c0100396:	89 45 f4             	mov    %eax,-0xc(%ebp)
    va_end(ap);
    return cnt;
c0100399:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010039c:	89 ec                	mov    %ebp,%esp
c010039e:	5d                   	pop    %ebp
c010039f:	c3                   	ret    

c01003a0 <cputchar>:

/* cputchar - writes a single character to stdout */
void
cputchar(int c) {
c01003a0:	55                   	push   %ebp
c01003a1:	89 e5                	mov    %esp,%ebp
c01003a3:	83 ec 18             	sub    $0x18,%esp
    cons_putc(c);
c01003a6:	8b 45 08             	mov    0x8(%ebp),%eax
c01003a9:	89 04 24             	mov    %eax,(%esp)
c01003ac:	e8 35 12 00 00       	call   c01015e6 <cons_putc>
}
c01003b1:	90                   	nop
c01003b2:	89 ec                	mov    %ebp,%esp
c01003b4:	5d                   	pop    %ebp
c01003b5:	c3                   	ret    

c01003b6 <cputs>:
/* *
 * cputs- writes the string pointed by @str to stdout and
 * appends a newline character.
 * */
int
cputs(const char *str) {
c01003b6:	55                   	push   %ebp
c01003b7:	89 e5                	mov    %esp,%ebp
c01003b9:	83 ec 28             	sub    $0x28,%esp
    int cnt = 0;
c01003bc:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    char c;
    while ((c = *str ++) != '\0') {
c01003c3:	eb 13                	jmp    c01003d8 <cputs+0x22>
        cputch(c, &cnt);
c01003c5:	0f be 45 f7          	movsbl -0x9(%ebp),%eax
c01003c9:	8d 55 f0             	lea    -0x10(%ebp),%edx
c01003cc:	89 54 24 04          	mov    %edx,0x4(%esp)
c01003d0:	89 04 24             	mov    %eax,(%esp)
c01003d3:	e8 48 ff ff ff       	call   c0100320 <cputch>
    while ((c = *str ++) != '\0') {
c01003d8:	8b 45 08             	mov    0x8(%ebp),%eax
c01003db:	8d 50 01             	lea    0x1(%eax),%edx
c01003de:	89 55 08             	mov    %edx,0x8(%ebp)
c01003e1:	0f b6 00             	movzbl (%eax),%eax
c01003e4:	88 45 f7             	mov    %al,-0x9(%ebp)
c01003e7:	80 7d f7 00          	cmpb   $0x0,-0x9(%ebp)
c01003eb:	75 d8                	jne    c01003c5 <cputs+0xf>
    }
    cputch('\n', &cnt);
c01003ed:	8d 45 f0             	lea    -0x10(%ebp),%eax
c01003f0:	89 44 24 04          	mov    %eax,0x4(%esp)
c01003f4:	c7 04 24 0a 00 00 00 	movl   $0xa,(%esp)
c01003fb:	e8 20 ff ff ff       	call   c0100320 <cputch>
    return cnt;
c0100400:	8b 45 f0             	mov    -0x10(%ebp),%eax
}
c0100403:	89 ec                	mov    %ebp,%esp
c0100405:	5d                   	pop    %ebp
c0100406:	c3                   	ret    

c0100407 <getchar>:

/* getchar - reads a single non-zero character from stdin */
int
getchar(void) {
c0100407:	55                   	push   %ebp
c0100408:	89 e5                	mov    %esp,%ebp
c010040a:	83 ec 18             	sub    $0x18,%esp
    int c;
    while ((c = cons_getc()) == 0)
c010040d:	90                   	nop
c010040e:	e8 12 12 00 00       	call   c0101625 <cons_getc>
c0100413:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0100416:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010041a:	74 f2                	je     c010040e <getchar+0x7>
        /* do nothing */;
    return c;
c010041c:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010041f:	89 ec                	mov    %ebp,%esp
c0100421:	5d                   	pop    %ebp
c0100422:	c3                   	ret    

c0100423 <stab_binsearch>:
 *      stab_binsearch(stabs, &left, &right, N_SO, 0xf0100184);
 * will exit setting left = 118, right = 554.
 * */
static void
stab_binsearch(const struct stab *stabs, int *region_left, int *region_right,
           int type, uintptr_t addr) {
c0100423:	55                   	push   %ebp
c0100424:	89 e5                	mov    %esp,%ebp
c0100426:	83 ec 20             	sub    $0x20,%esp
    int l = *region_left, r = *region_right, any_matches = 0;
c0100429:	8b 45 0c             	mov    0xc(%ebp),%eax
c010042c:	8b 00                	mov    (%eax),%eax
c010042e:	89 45 fc             	mov    %eax,-0x4(%ebp)
c0100431:	8b 45 10             	mov    0x10(%ebp),%eax
c0100434:	8b 00                	mov    (%eax),%eax
c0100436:	89 45 f8             	mov    %eax,-0x8(%ebp)
c0100439:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)

    while (l <= r) {
c0100440:	e9 ca 00 00 00       	jmp    c010050f <stab_binsearch+0xec>
        int true_m = (l + r) / 2, m = true_m;
c0100445:	8b 55 fc             	mov    -0x4(%ebp),%edx
c0100448:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010044b:	01 d0                	add    %edx,%eax
c010044d:	89 c2                	mov    %eax,%edx
c010044f:	c1 ea 1f             	shr    $0x1f,%edx
c0100452:	01 d0                	add    %edx,%eax
c0100454:	d1 f8                	sar    %eax
c0100456:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0100459:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010045c:	89 45 f0             	mov    %eax,-0x10(%ebp)

        // search for earliest stab with right type
        while (m >= l && stabs[m].n_type != type) {
c010045f:	eb 03                	jmp    c0100464 <stab_binsearch+0x41>
            m --;
c0100461:	ff 4d f0             	decl   -0x10(%ebp)
        while (m >= l && stabs[m].n_type != type) {
c0100464:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0100467:	3b 45 fc             	cmp    -0x4(%ebp),%eax
c010046a:	7c 1f                	jl     c010048b <stab_binsearch+0x68>
c010046c:	8b 55 f0             	mov    -0x10(%ebp),%edx
c010046f:	89 d0                	mov    %edx,%eax
c0100471:	01 c0                	add    %eax,%eax
c0100473:	01 d0                	add    %edx,%eax
c0100475:	c1 e0 02             	shl    $0x2,%eax
c0100478:	89 c2                	mov    %eax,%edx
c010047a:	8b 45 08             	mov    0x8(%ebp),%eax
c010047d:	01 d0                	add    %edx,%eax
c010047f:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c0100483:	0f b6 c0             	movzbl %al,%eax
c0100486:	39 45 14             	cmp    %eax,0x14(%ebp)
c0100489:	75 d6                	jne    c0100461 <stab_binsearch+0x3e>
        }
        if (m < l) {    // no match in [l, m]
c010048b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010048e:	3b 45 fc             	cmp    -0x4(%ebp),%eax
c0100491:	7d 09                	jge    c010049c <stab_binsearch+0x79>
            l = true_m + 1;
c0100493:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0100496:	40                   	inc    %eax
c0100497:	89 45 fc             	mov    %eax,-0x4(%ebp)
            continue;
c010049a:	eb 73                	jmp    c010050f <stab_binsearch+0xec>
        }

        // actual binary search
        any_matches = 1;
c010049c:	c7 45 f4 01 00 00 00 	movl   $0x1,-0xc(%ebp)
        if (stabs[m].n_value < addr) {
c01004a3:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01004a6:	89 d0                	mov    %edx,%eax
c01004a8:	01 c0                	add    %eax,%eax
c01004aa:	01 d0                	add    %edx,%eax
c01004ac:	c1 e0 02             	shl    $0x2,%eax
c01004af:	89 c2                	mov    %eax,%edx
c01004b1:	8b 45 08             	mov    0x8(%ebp),%eax
c01004b4:	01 d0                	add    %edx,%eax
c01004b6:	8b 40 08             	mov    0x8(%eax),%eax
c01004b9:	39 45 18             	cmp    %eax,0x18(%ebp)
c01004bc:	76 11                	jbe    c01004cf <stab_binsearch+0xac>
            *region_left = m;
c01004be:	8b 45 0c             	mov    0xc(%ebp),%eax
c01004c1:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01004c4:	89 10                	mov    %edx,(%eax)
            l = true_m + 1;
c01004c6:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01004c9:	40                   	inc    %eax
c01004ca:	89 45 fc             	mov    %eax,-0x4(%ebp)
c01004cd:	eb 40                	jmp    c010050f <stab_binsearch+0xec>
        } else if (stabs[m].n_value > addr) {
c01004cf:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01004d2:	89 d0                	mov    %edx,%eax
c01004d4:	01 c0                	add    %eax,%eax
c01004d6:	01 d0                	add    %edx,%eax
c01004d8:	c1 e0 02             	shl    $0x2,%eax
c01004db:	89 c2                	mov    %eax,%edx
c01004dd:	8b 45 08             	mov    0x8(%ebp),%eax
c01004e0:	01 d0                	add    %edx,%eax
c01004e2:	8b 40 08             	mov    0x8(%eax),%eax
c01004e5:	39 45 18             	cmp    %eax,0x18(%ebp)
c01004e8:	73 14                	jae    c01004fe <stab_binsearch+0xdb>
            *region_right = m - 1;
c01004ea:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01004ed:	8d 50 ff             	lea    -0x1(%eax),%edx
c01004f0:	8b 45 10             	mov    0x10(%ebp),%eax
c01004f3:	89 10                	mov    %edx,(%eax)
            r = m - 1;
c01004f5:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01004f8:	48                   	dec    %eax
c01004f9:	89 45 f8             	mov    %eax,-0x8(%ebp)
c01004fc:	eb 11                	jmp    c010050f <stab_binsearch+0xec>
        } else {
            // exact match for 'addr', but continue loop to find
            // *region_right
            *region_left = m;
c01004fe:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100501:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0100504:	89 10                	mov    %edx,(%eax)
            l = m;
c0100506:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0100509:	89 45 fc             	mov    %eax,-0x4(%ebp)
            addr ++;
c010050c:	ff 45 18             	incl   0x18(%ebp)
    while (l <= r) {
c010050f:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100512:	3b 45 f8             	cmp    -0x8(%ebp),%eax
c0100515:	0f 8e 2a ff ff ff    	jle    c0100445 <stab_binsearch+0x22>
        }
    }

    if (!any_matches) {
c010051b:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010051f:	75 0f                	jne    c0100530 <stab_binsearch+0x10d>
        *region_right = *region_left - 1;
c0100521:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100524:	8b 00                	mov    (%eax),%eax
c0100526:	8d 50 ff             	lea    -0x1(%eax),%edx
c0100529:	8b 45 10             	mov    0x10(%ebp),%eax
c010052c:	89 10                	mov    %edx,(%eax)
        l = *region_right;
        for (; l > *region_left && stabs[l].n_type != type; l --)
            /* do nothing */;
        *region_left = l;
    }
}
c010052e:	eb 3e                	jmp    c010056e <stab_binsearch+0x14b>
        l = *region_right;
c0100530:	8b 45 10             	mov    0x10(%ebp),%eax
c0100533:	8b 00                	mov    (%eax),%eax
c0100535:	89 45 fc             	mov    %eax,-0x4(%ebp)
        for (; l > *region_left && stabs[l].n_type != type; l --)
c0100538:	eb 03                	jmp    c010053d <stab_binsearch+0x11a>
c010053a:	ff 4d fc             	decl   -0x4(%ebp)
c010053d:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100540:	8b 00                	mov    (%eax),%eax
c0100542:	39 45 fc             	cmp    %eax,-0x4(%ebp)
c0100545:	7e 1f                	jle    c0100566 <stab_binsearch+0x143>
c0100547:	8b 55 fc             	mov    -0x4(%ebp),%edx
c010054a:	89 d0                	mov    %edx,%eax
c010054c:	01 c0                	add    %eax,%eax
c010054e:	01 d0                	add    %edx,%eax
c0100550:	c1 e0 02             	shl    $0x2,%eax
c0100553:	89 c2                	mov    %eax,%edx
c0100555:	8b 45 08             	mov    0x8(%ebp),%eax
c0100558:	01 d0                	add    %edx,%eax
c010055a:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c010055e:	0f b6 c0             	movzbl %al,%eax
c0100561:	39 45 14             	cmp    %eax,0x14(%ebp)
c0100564:	75 d4                	jne    c010053a <stab_binsearch+0x117>
        *region_left = l;
c0100566:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100569:	8b 55 fc             	mov    -0x4(%ebp),%edx
c010056c:	89 10                	mov    %edx,(%eax)
}
c010056e:	90                   	nop
c010056f:	89 ec                	mov    %ebp,%esp
c0100571:	5d                   	pop    %ebp
c0100572:	c3                   	ret    

c0100573 <debuginfo_eip>:
 * the specified instruction address, @addr.  Returns 0 if information
 * was found, and negative if not.  But even if it returns negative it
 * has stored some information into '*info'.
 * */
int
debuginfo_eip(uintptr_t addr, struct eipdebuginfo *info) {
c0100573:	55                   	push   %ebp
c0100574:	89 e5                	mov    %esp,%ebp
c0100576:	83 ec 58             	sub    $0x58,%esp
    const struct stab *stabs, *stab_end;
    const char *stabstr, *stabstr_end;

    info->eip_file = "<unknown>";
c0100579:	8b 45 0c             	mov    0xc(%ebp),%eax
c010057c:	c7 00 2c a1 10 c0    	movl   $0xc010a12c,(%eax)
    info->eip_line = 0;
c0100582:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100585:	c7 40 04 00 00 00 00 	movl   $0x0,0x4(%eax)
    info->eip_fn_name = "<unknown>";
c010058c:	8b 45 0c             	mov    0xc(%ebp),%eax
c010058f:	c7 40 08 2c a1 10 c0 	movl   $0xc010a12c,0x8(%eax)
    info->eip_fn_namelen = 9;
c0100596:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100599:	c7 40 0c 09 00 00 00 	movl   $0x9,0xc(%eax)
    info->eip_fn_addr = addr;
c01005a0:	8b 45 0c             	mov    0xc(%ebp),%eax
c01005a3:	8b 55 08             	mov    0x8(%ebp),%edx
c01005a6:	89 50 10             	mov    %edx,0x10(%eax)
    info->eip_fn_narg = 0;
c01005a9:	8b 45 0c             	mov    0xc(%ebp),%eax
c01005ac:	c7 40 14 00 00 00 00 	movl   $0x0,0x14(%eax)

    stabs = __STAB_BEGIN__;
c01005b3:	c7 45 f4 b8 c3 10 c0 	movl   $0xc010c3b8,-0xc(%ebp)
    stab_end = __STAB_END__;
c01005ba:	c7 45 f0 24 f0 11 c0 	movl   $0xc011f024,-0x10(%ebp)
    stabstr = __STABSTR_BEGIN__;
c01005c1:	c7 45 ec 25 f0 11 c0 	movl   $0xc011f025,-0x14(%ebp)
    stabstr_end = __STABSTR_END__;
c01005c8:	c7 45 e8 b4 54 12 c0 	movl   $0xc01254b4,-0x18(%ebp)

    // String table validity checks
    if (stabstr_end <= stabstr || stabstr_end[-1] != 0) {
c01005cf:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01005d2:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c01005d5:	76 0b                	jbe    c01005e2 <debuginfo_eip+0x6f>
c01005d7:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01005da:	48                   	dec    %eax
c01005db:	0f b6 00             	movzbl (%eax),%eax
c01005de:	84 c0                	test   %al,%al
c01005e0:	74 0a                	je     c01005ec <debuginfo_eip+0x79>
        return -1;
c01005e2:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c01005e7:	e9 ab 02 00 00       	jmp    c0100897 <debuginfo_eip+0x324>
    // 'eip'.  First, we find the basic source file containing 'eip'.
    // Then, we look in that source file for the function.  Then we look
    // for the line number.

    // Search the entire set of stabs for the source file (type N_SO).
    int lfile = 0, rfile = (stab_end - stabs) - 1;
c01005ec:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
c01005f3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01005f6:	2b 45 f4             	sub    -0xc(%ebp),%eax
c01005f9:	c1 f8 02             	sar    $0x2,%eax
c01005fc:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
c0100602:	48                   	dec    %eax
c0100603:	89 45 e0             	mov    %eax,-0x20(%ebp)
    stab_binsearch(stabs, &lfile, &rfile, N_SO, addr);
c0100606:	8b 45 08             	mov    0x8(%ebp),%eax
c0100609:	89 44 24 10          	mov    %eax,0x10(%esp)
c010060d:	c7 44 24 0c 64 00 00 	movl   $0x64,0xc(%esp)
c0100614:	00 
c0100615:	8d 45 e0             	lea    -0x20(%ebp),%eax
c0100618:	89 44 24 08          	mov    %eax,0x8(%esp)
c010061c:	8d 45 e4             	lea    -0x1c(%ebp),%eax
c010061f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100623:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100626:	89 04 24             	mov    %eax,(%esp)
c0100629:	e8 f5 fd ff ff       	call   c0100423 <stab_binsearch>
    if (lfile == 0)
c010062e:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100631:	85 c0                	test   %eax,%eax
c0100633:	75 0a                	jne    c010063f <debuginfo_eip+0xcc>
        return -1;
c0100635:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c010063a:	e9 58 02 00 00       	jmp    c0100897 <debuginfo_eip+0x324>

    // Search within that file's stabs for the function definition
    // (N_FUN).
    int lfun = lfile, rfun = rfile;
c010063f:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100642:	89 45 dc             	mov    %eax,-0x24(%ebp)
c0100645:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0100648:	89 45 d8             	mov    %eax,-0x28(%ebp)
    int lline, rline;
    stab_binsearch(stabs, &lfun, &rfun, N_FUN, addr);
c010064b:	8b 45 08             	mov    0x8(%ebp),%eax
c010064e:	89 44 24 10          	mov    %eax,0x10(%esp)
c0100652:	c7 44 24 0c 24 00 00 	movl   $0x24,0xc(%esp)
c0100659:	00 
c010065a:	8d 45 d8             	lea    -0x28(%ebp),%eax
c010065d:	89 44 24 08          	mov    %eax,0x8(%esp)
c0100661:	8d 45 dc             	lea    -0x24(%ebp),%eax
c0100664:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100668:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010066b:	89 04 24             	mov    %eax,(%esp)
c010066e:	e8 b0 fd ff ff       	call   c0100423 <stab_binsearch>

    if (lfun <= rfun) {
c0100673:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0100676:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0100679:	39 c2                	cmp    %eax,%edx
c010067b:	7f 78                	jg     c01006f5 <debuginfo_eip+0x182>
        // stabs[lfun] points to the function name
        // in the string table, but check bounds just in case.
        if (stabs[lfun].n_strx < stabstr_end - stabstr) {
c010067d:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0100680:	89 c2                	mov    %eax,%edx
c0100682:	89 d0                	mov    %edx,%eax
c0100684:	01 c0                	add    %eax,%eax
c0100686:	01 d0                	add    %edx,%eax
c0100688:	c1 e0 02             	shl    $0x2,%eax
c010068b:	89 c2                	mov    %eax,%edx
c010068d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100690:	01 d0                	add    %edx,%eax
c0100692:	8b 10                	mov    (%eax),%edx
c0100694:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0100697:	2b 45 ec             	sub    -0x14(%ebp),%eax
c010069a:	39 c2                	cmp    %eax,%edx
c010069c:	73 22                	jae    c01006c0 <debuginfo_eip+0x14d>
            info->eip_fn_name = stabstr + stabs[lfun].n_strx;
c010069e:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01006a1:	89 c2                	mov    %eax,%edx
c01006a3:	89 d0                	mov    %edx,%eax
c01006a5:	01 c0                	add    %eax,%eax
c01006a7:	01 d0                	add    %edx,%eax
c01006a9:	c1 e0 02             	shl    $0x2,%eax
c01006ac:	89 c2                	mov    %eax,%edx
c01006ae:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01006b1:	01 d0                	add    %edx,%eax
c01006b3:	8b 10                	mov    (%eax),%edx
c01006b5:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01006b8:	01 c2                	add    %eax,%edx
c01006ba:	8b 45 0c             	mov    0xc(%ebp),%eax
c01006bd:	89 50 08             	mov    %edx,0x8(%eax)
        }
        info->eip_fn_addr = stabs[lfun].n_value;
c01006c0:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01006c3:	89 c2                	mov    %eax,%edx
c01006c5:	89 d0                	mov    %edx,%eax
c01006c7:	01 c0                	add    %eax,%eax
c01006c9:	01 d0                	add    %edx,%eax
c01006cb:	c1 e0 02             	shl    $0x2,%eax
c01006ce:	89 c2                	mov    %eax,%edx
c01006d0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01006d3:	01 d0                	add    %edx,%eax
c01006d5:	8b 50 08             	mov    0x8(%eax),%edx
c01006d8:	8b 45 0c             	mov    0xc(%ebp),%eax
c01006db:	89 50 10             	mov    %edx,0x10(%eax)
        addr -= info->eip_fn_addr;
c01006de:	8b 45 0c             	mov    0xc(%ebp),%eax
c01006e1:	8b 40 10             	mov    0x10(%eax),%eax
c01006e4:	29 45 08             	sub    %eax,0x8(%ebp)
        // Search within the function definition for the line number.
        lline = lfun;
c01006e7:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01006ea:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        rline = rfun;
c01006ed:	8b 45 d8             	mov    -0x28(%ebp),%eax
c01006f0:	89 45 d0             	mov    %eax,-0x30(%ebp)
c01006f3:	eb 15                	jmp    c010070a <debuginfo_eip+0x197>
    } else {
        // Couldn't find function stab!  Maybe we're in an assembly
        // file.  Search the whole file for the line number.
        info->eip_fn_addr = addr;
c01006f5:	8b 45 0c             	mov    0xc(%ebp),%eax
c01006f8:	8b 55 08             	mov    0x8(%ebp),%edx
c01006fb:	89 50 10             	mov    %edx,0x10(%eax)
        lline = lfile;
c01006fe:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0100701:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        rline = rfile;
c0100704:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0100707:	89 45 d0             	mov    %eax,-0x30(%ebp)
    }
    info->eip_fn_namelen = strfind(info->eip_fn_name, ':') - info->eip_fn_name;
c010070a:	8b 45 0c             	mov    0xc(%ebp),%eax
c010070d:	8b 40 08             	mov    0x8(%eax),%eax
c0100710:	c7 44 24 04 3a 00 00 	movl   $0x3a,0x4(%esp)
c0100717:	00 
c0100718:	89 04 24             	mov    %eax,(%esp)
c010071b:	e8 3c 96 00 00       	call   c0109d5c <strfind>
c0100720:	8b 55 0c             	mov    0xc(%ebp),%edx
c0100723:	8b 4a 08             	mov    0x8(%edx),%ecx
c0100726:	29 c8                	sub    %ecx,%eax
c0100728:	89 c2                	mov    %eax,%edx
c010072a:	8b 45 0c             	mov    0xc(%ebp),%eax
c010072d:	89 50 0c             	mov    %edx,0xc(%eax)

    // Search within [lline, rline] for the line number stab.
    // If found, set info->eip_line to the right line number.
    // If not found, return -1.
    stab_binsearch(stabs, &lline, &rline, N_SLINE, addr);
c0100730:	8b 45 08             	mov    0x8(%ebp),%eax
c0100733:	89 44 24 10          	mov    %eax,0x10(%esp)
c0100737:	c7 44 24 0c 44 00 00 	movl   $0x44,0xc(%esp)
c010073e:	00 
c010073f:	8d 45 d0             	lea    -0x30(%ebp),%eax
c0100742:	89 44 24 08          	mov    %eax,0x8(%esp)
c0100746:	8d 45 d4             	lea    -0x2c(%ebp),%eax
c0100749:	89 44 24 04          	mov    %eax,0x4(%esp)
c010074d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100750:	89 04 24             	mov    %eax,(%esp)
c0100753:	e8 cb fc ff ff       	call   c0100423 <stab_binsearch>
    if (lline <= rline) {
c0100758:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010075b:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010075e:	39 c2                	cmp    %eax,%edx
c0100760:	7f 23                	jg     c0100785 <debuginfo_eip+0x212>
        info->eip_line = stabs[rline].n_desc;
c0100762:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0100765:	89 c2                	mov    %eax,%edx
c0100767:	89 d0                	mov    %edx,%eax
c0100769:	01 c0                	add    %eax,%eax
c010076b:	01 d0                	add    %edx,%eax
c010076d:	c1 e0 02             	shl    $0x2,%eax
c0100770:	89 c2                	mov    %eax,%edx
c0100772:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100775:	01 d0                	add    %edx,%eax
c0100777:	0f b7 40 06          	movzwl 0x6(%eax),%eax
c010077b:	89 c2                	mov    %eax,%edx
c010077d:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100780:	89 50 04             	mov    %edx,0x4(%eax)

    // Search backwards from the line number for the relevant filename stab.
    // We can't just use the "lfile" stab because inlined functions
    // can interpolate code from a different file!
    // Such included source files use the N_SOL stab type.
    while (lline >= lfile
c0100783:	eb 11                	jmp    c0100796 <debuginfo_eip+0x223>
        return -1;
c0100785:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c010078a:	e9 08 01 00 00       	jmp    c0100897 <debuginfo_eip+0x324>
           && stabs[lline].n_type != N_SOL
           && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) {
        lline --;
c010078f:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100792:	48                   	dec    %eax
c0100793:	89 45 d4             	mov    %eax,-0x2c(%ebp)
    while (lline >= lfile
c0100796:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0100799:	8b 45 e4             	mov    -0x1c(%ebp),%eax
           && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) {
c010079c:	39 c2                	cmp    %eax,%edx
c010079e:	7c 56                	jl     c01007f6 <debuginfo_eip+0x283>
           && stabs[lline].n_type != N_SOL
c01007a0:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01007a3:	89 c2                	mov    %eax,%edx
c01007a5:	89 d0                	mov    %edx,%eax
c01007a7:	01 c0                	add    %eax,%eax
c01007a9:	01 d0                	add    %edx,%eax
c01007ab:	c1 e0 02             	shl    $0x2,%eax
c01007ae:	89 c2                	mov    %eax,%edx
c01007b0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01007b3:	01 d0                	add    %edx,%eax
c01007b5:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c01007b9:	3c 84                	cmp    $0x84,%al
c01007bb:	74 39                	je     c01007f6 <debuginfo_eip+0x283>
           && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) {
c01007bd:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01007c0:	89 c2                	mov    %eax,%edx
c01007c2:	89 d0                	mov    %edx,%eax
c01007c4:	01 c0                	add    %eax,%eax
c01007c6:	01 d0                	add    %edx,%eax
c01007c8:	c1 e0 02             	shl    $0x2,%eax
c01007cb:	89 c2                	mov    %eax,%edx
c01007cd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01007d0:	01 d0                	add    %edx,%eax
c01007d2:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c01007d6:	3c 64                	cmp    $0x64,%al
c01007d8:	75 b5                	jne    c010078f <debuginfo_eip+0x21c>
c01007da:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01007dd:	89 c2                	mov    %eax,%edx
c01007df:	89 d0                	mov    %edx,%eax
c01007e1:	01 c0                	add    %eax,%eax
c01007e3:	01 d0                	add    %edx,%eax
c01007e5:	c1 e0 02             	shl    $0x2,%eax
c01007e8:	89 c2                	mov    %eax,%edx
c01007ea:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01007ed:	01 d0                	add    %edx,%eax
c01007ef:	8b 40 08             	mov    0x8(%eax),%eax
c01007f2:	85 c0                	test   %eax,%eax
c01007f4:	74 99                	je     c010078f <debuginfo_eip+0x21c>
    }
    if (lline >= lfile && stabs[lline].n_strx < stabstr_end - stabstr) {
c01007f6:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01007f9:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01007fc:	39 c2                	cmp    %eax,%edx
c01007fe:	7c 42                	jl     c0100842 <debuginfo_eip+0x2cf>
c0100800:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100803:	89 c2                	mov    %eax,%edx
c0100805:	89 d0                	mov    %edx,%eax
c0100807:	01 c0                	add    %eax,%eax
c0100809:	01 d0                	add    %edx,%eax
c010080b:	c1 e0 02             	shl    $0x2,%eax
c010080e:	89 c2                	mov    %eax,%edx
c0100810:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100813:	01 d0                	add    %edx,%eax
c0100815:	8b 10                	mov    (%eax),%edx
c0100817:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010081a:	2b 45 ec             	sub    -0x14(%ebp),%eax
c010081d:	39 c2                	cmp    %eax,%edx
c010081f:	73 21                	jae    c0100842 <debuginfo_eip+0x2cf>
        info->eip_file = stabstr + stabs[lline].n_strx;
c0100821:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100824:	89 c2                	mov    %eax,%edx
c0100826:	89 d0                	mov    %edx,%eax
c0100828:	01 c0                	add    %eax,%eax
c010082a:	01 d0                	add    %edx,%eax
c010082c:	c1 e0 02             	shl    $0x2,%eax
c010082f:	89 c2                	mov    %eax,%edx
c0100831:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100834:	01 d0                	add    %edx,%eax
c0100836:	8b 10                	mov    (%eax),%edx
c0100838:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010083b:	01 c2                	add    %eax,%edx
c010083d:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100840:	89 10                	mov    %edx,(%eax)
    }

    // Set eip_fn_narg to the number of arguments taken by the function,
    // or 0 if there was no containing function.
    if (lfun < rfun) {
c0100842:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0100845:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0100848:	39 c2                	cmp    %eax,%edx
c010084a:	7d 46                	jge    c0100892 <debuginfo_eip+0x31f>
        for (lline = lfun + 1;
c010084c:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010084f:	40                   	inc    %eax
c0100850:	89 45 d4             	mov    %eax,-0x2c(%ebp)
c0100853:	eb 16                	jmp    c010086b <debuginfo_eip+0x2f8>
             lline < rfun && stabs[lline].n_type == N_PSYM;
             lline ++) {
            info->eip_fn_narg ++;
c0100855:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100858:	8b 40 14             	mov    0x14(%eax),%eax
c010085b:	8d 50 01             	lea    0x1(%eax),%edx
c010085e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100861:	89 50 14             	mov    %edx,0x14(%eax)
             lline ++) {
c0100864:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100867:	40                   	inc    %eax
c0100868:	89 45 d4             	mov    %eax,-0x2c(%ebp)
             lline < rfun && stabs[lline].n_type == N_PSYM;
c010086b:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010086e:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0100871:	39 c2                	cmp    %eax,%edx
c0100873:	7d 1d                	jge    c0100892 <debuginfo_eip+0x31f>
c0100875:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0100878:	89 c2                	mov    %eax,%edx
c010087a:	89 d0                	mov    %edx,%eax
c010087c:	01 c0                	add    %eax,%eax
c010087e:	01 d0                	add    %edx,%eax
c0100880:	c1 e0 02             	shl    $0x2,%eax
c0100883:	89 c2                	mov    %eax,%edx
c0100885:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100888:	01 d0                	add    %edx,%eax
c010088a:	0f b6 40 04          	movzbl 0x4(%eax),%eax
c010088e:	3c a0                	cmp    $0xa0,%al
c0100890:	74 c3                	je     c0100855 <debuginfo_eip+0x2e2>
        }
    }
    return 0;
c0100892:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100897:	89 ec                	mov    %ebp,%esp
c0100899:	5d                   	pop    %ebp
c010089a:	c3                   	ret    

c010089b <print_kerninfo>:
 * print_kerninfo - print the information about kernel, including the location
 * of kernel entry, the start addresses of data and text segements, the start
 * address of free memory and how many memory that kernel has used.
 * */
void
print_kerninfo(void) {
c010089b:	55                   	push   %ebp
c010089c:	89 e5                	mov    %esp,%ebp
c010089e:	83 ec 18             	sub    $0x18,%esp
    extern char etext[], edata[], end[], kern_init[];
    cprintf("Special kernel symbols:\n");
c01008a1:	c7 04 24 36 a1 10 c0 	movl   $0xc010a136,(%esp)
c01008a8:	e8 cb fa ff ff       	call   c0100378 <cprintf>
    cprintf("  entry  0x%08x (phys)\n", kern_init);
c01008ad:	c7 44 24 04 36 00 10 	movl   $0xc0100036,0x4(%esp)
c01008b4:	c0 
c01008b5:	c7 04 24 4f a1 10 c0 	movl   $0xc010a14f,(%esp)
c01008bc:	e8 b7 fa ff ff       	call   c0100378 <cprintf>
    cprintf("  etext  0x%08x (phys)\n", etext);
c01008c1:	c7 44 24 04 70 a0 10 	movl   $0xc010a070,0x4(%esp)
c01008c8:	c0 
c01008c9:	c7 04 24 67 a1 10 c0 	movl   $0xc010a167,(%esp)
c01008d0:	e8 a3 fa ff ff       	call   c0100378 <cprintf>
    cprintf("  edata  0x%08x (phys)\n", edata);
c01008d5:	c7 44 24 04 00 b0 12 	movl   $0xc012b000,0x4(%esp)
c01008dc:	c0 
c01008dd:	c7 04 24 7f a1 10 c0 	movl   $0xc010a17f,(%esp)
c01008e4:	e8 8f fa ff ff       	call   c0100378 <cprintf>
    cprintf("  end    0x%08x (phys)\n", end);
c01008e9:	c7 44 24 04 b4 e1 12 	movl   $0xc012e1b4,0x4(%esp)
c01008f0:	c0 
c01008f1:	c7 04 24 97 a1 10 c0 	movl   $0xc010a197,(%esp)
c01008f8:	e8 7b fa ff ff       	call   c0100378 <cprintf>
    cprintf("Kernel executable memory footprint: %dKB\n", (end - kern_init + 1023)/1024);
c01008fd:	b8 b4 e1 12 c0       	mov    $0xc012e1b4,%eax
c0100902:	2d 36 00 10 c0       	sub    $0xc0100036,%eax
c0100907:	05 ff 03 00 00       	add    $0x3ff,%eax
c010090c:	8d 90 ff 03 00 00    	lea    0x3ff(%eax),%edx
c0100912:	85 c0                	test   %eax,%eax
c0100914:	0f 48 c2             	cmovs  %edx,%eax
c0100917:	c1 f8 0a             	sar    $0xa,%eax
c010091a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010091e:	c7 04 24 b0 a1 10 c0 	movl   $0xc010a1b0,(%esp)
c0100925:	e8 4e fa ff ff       	call   c0100378 <cprintf>
}
c010092a:	90                   	nop
c010092b:	89 ec                	mov    %ebp,%esp
c010092d:	5d                   	pop    %ebp
c010092e:	c3                   	ret    

c010092f <print_debuginfo>:
/* *
 * print_debuginfo - read and print the stat information for the address @eip,
 * and info.eip_fn_addr should be the first address of the related function.
 * */
void
print_debuginfo(uintptr_t eip) {
c010092f:	55                   	push   %ebp
c0100930:	89 e5                	mov    %esp,%ebp
c0100932:	81 ec 48 01 00 00    	sub    $0x148,%esp
    struct eipdebuginfo info;
    if (debuginfo_eip(eip, &info) != 0) {
c0100938:	8d 45 dc             	lea    -0x24(%ebp),%eax
c010093b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010093f:	8b 45 08             	mov    0x8(%ebp),%eax
c0100942:	89 04 24             	mov    %eax,(%esp)
c0100945:	e8 29 fc ff ff       	call   c0100573 <debuginfo_eip>
c010094a:	85 c0                	test   %eax,%eax
c010094c:	74 15                	je     c0100963 <print_debuginfo+0x34>
        cprintf("    <unknow>: -- 0x%08x --\n", eip);
c010094e:	8b 45 08             	mov    0x8(%ebp),%eax
c0100951:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100955:	c7 04 24 da a1 10 c0 	movl   $0xc010a1da,(%esp)
c010095c:	e8 17 fa ff ff       	call   c0100378 <cprintf>
        }
        fnname[j] = '\0';
        cprintf("    %s:%d: %s+%d\n", info.eip_file, info.eip_line,
                fnname, eip - info.eip_fn_addr);
    }
}
c0100961:	eb 6c                	jmp    c01009cf <print_debuginfo+0xa0>
        for (j = 0; j < info.eip_fn_namelen; j ++) {
c0100963:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c010096a:	eb 1b                	jmp    c0100987 <print_debuginfo+0x58>
            fnname[j] = info.eip_fn_name[j];
c010096c:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c010096f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100972:	01 d0                	add    %edx,%eax
c0100974:	0f b6 10             	movzbl (%eax),%edx
c0100977:	8d 8d dc fe ff ff    	lea    -0x124(%ebp),%ecx
c010097d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100980:	01 c8                	add    %ecx,%eax
c0100982:	88 10                	mov    %dl,(%eax)
        for (j = 0; j < info.eip_fn_namelen; j ++) {
c0100984:	ff 45 f4             	incl   -0xc(%ebp)
c0100987:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010098a:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c010098d:	7c dd                	jl     c010096c <print_debuginfo+0x3d>
        fnname[j] = '\0';
c010098f:	8d 95 dc fe ff ff    	lea    -0x124(%ebp),%edx
c0100995:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100998:	01 d0                	add    %edx,%eax
c010099a:	c6 00 00             	movb   $0x0,(%eax)
                fnname, eip - info.eip_fn_addr);
c010099d:	8b 55 ec             	mov    -0x14(%ebp),%edx
        cprintf("    %s:%d: %s+%d\n", info.eip_file, info.eip_line,
c01009a0:	8b 45 08             	mov    0x8(%ebp),%eax
c01009a3:	29 d0                	sub    %edx,%eax
c01009a5:	89 c1                	mov    %eax,%ecx
c01009a7:	8b 55 e0             	mov    -0x20(%ebp),%edx
c01009aa:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01009ad:	89 4c 24 10          	mov    %ecx,0x10(%esp)
c01009b1:	8d 8d dc fe ff ff    	lea    -0x124(%ebp),%ecx
c01009b7:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c01009bb:	89 54 24 08          	mov    %edx,0x8(%esp)
c01009bf:	89 44 24 04          	mov    %eax,0x4(%esp)
c01009c3:	c7 04 24 f6 a1 10 c0 	movl   $0xc010a1f6,(%esp)
c01009ca:	e8 a9 f9 ff ff       	call   c0100378 <cprintf>
}
c01009cf:	90                   	nop
c01009d0:	89 ec                	mov    %ebp,%esp
c01009d2:	5d                   	pop    %ebp
c01009d3:	c3                   	ret    

c01009d4 <read_eip>:

static __noinline uint32_t
read_eip(void) {
c01009d4:	55                   	push   %ebp
c01009d5:	89 e5                	mov    %esp,%ebp
c01009d7:	83 ec 10             	sub    $0x10,%esp
    uint32_t eip;
    asm volatile("movl 4(%%ebp), %0" : "=r" (eip));
c01009da:	8b 45 04             	mov    0x4(%ebp),%eax
c01009dd:	89 45 fc             	mov    %eax,-0x4(%ebp)
    return eip;
c01009e0:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c01009e3:	89 ec                	mov    %ebp,%esp
c01009e5:	5d                   	pop    %ebp
c01009e6:	c3                   	ret    

c01009e7 <print_stackframe>:
 *
 * Note that, the length of ebp-chain is limited. In boot/bootasm.S, before jumping
 * to the kernel entry, the value of ebp has been set to zero, that's the boundary.
 * */
void
print_stackframe(void) {
c01009e7:	55                   	push   %ebp
c01009e8:	89 e5                	mov    %esp,%ebp
      *    (3.4) call print_debuginfo(eip-1) to print the C calling function name and line number, etc.
      *    (3.5) popup a calling stackframe
      *           NOTICE: the calling funciton's return addr eip  = ss:[ebp+4]
      *                   the calling funciton's ebp = ss:[ebp]
      */
}
c01009ea:	90                   	nop
c01009eb:	5d                   	pop    %ebp
c01009ec:	c3                   	ret    

c01009ed <parse>:
#define MAXARGS         16
#define WHITESPACE      " \t\n\r"

/* parse - parse the command buffer into whitespace-separated arguments */
static int
parse(char *buf, char **argv) {
c01009ed:	55                   	push   %ebp
c01009ee:	89 e5                	mov    %esp,%ebp
c01009f0:	83 ec 28             	sub    $0x28,%esp
    int argc = 0;
c01009f3:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    while (1) {
        // find global whitespace
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
c01009fa:	eb 0c                	jmp    c0100a08 <parse+0x1b>
            *buf ++ = '\0';
c01009fc:	8b 45 08             	mov    0x8(%ebp),%eax
c01009ff:	8d 50 01             	lea    0x1(%eax),%edx
c0100a02:	89 55 08             	mov    %edx,0x8(%ebp)
c0100a05:	c6 00 00             	movb   $0x0,(%eax)
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
c0100a08:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a0b:	0f b6 00             	movzbl (%eax),%eax
c0100a0e:	84 c0                	test   %al,%al
c0100a10:	74 1d                	je     c0100a2f <parse+0x42>
c0100a12:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a15:	0f b6 00             	movzbl (%eax),%eax
c0100a18:	0f be c0             	movsbl %al,%eax
c0100a1b:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100a1f:	c7 04 24 88 a2 10 c0 	movl   $0xc010a288,(%esp)
c0100a26:	e8 fd 92 00 00       	call   c0109d28 <strchr>
c0100a2b:	85 c0                	test   %eax,%eax
c0100a2d:	75 cd                	jne    c01009fc <parse+0xf>
        }
        if (*buf == '\0') {
c0100a2f:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a32:	0f b6 00             	movzbl (%eax),%eax
c0100a35:	84 c0                	test   %al,%al
c0100a37:	74 65                	je     c0100a9e <parse+0xb1>
            break;
        }

        // save and scan past next arg
        if (argc == MAXARGS - 1) {
c0100a39:	83 7d f4 0f          	cmpl   $0xf,-0xc(%ebp)
c0100a3d:	75 14                	jne    c0100a53 <parse+0x66>
            cprintf("Too many arguments (max %d).\n", MAXARGS);
c0100a3f:	c7 44 24 04 10 00 00 	movl   $0x10,0x4(%esp)
c0100a46:	00 
c0100a47:	c7 04 24 8d a2 10 c0 	movl   $0xc010a28d,(%esp)
c0100a4e:	e8 25 f9 ff ff       	call   c0100378 <cprintf>
        }
        argv[argc ++] = buf;
c0100a53:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100a56:	8d 50 01             	lea    0x1(%eax),%edx
c0100a59:	89 55 f4             	mov    %edx,-0xc(%ebp)
c0100a5c:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0100a63:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100a66:	01 c2                	add    %eax,%edx
c0100a68:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a6b:	89 02                	mov    %eax,(%edx)
        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
c0100a6d:	eb 03                	jmp    c0100a72 <parse+0x85>
            buf ++;
c0100a6f:	ff 45 08             	incl   0x8(%ebp)
        while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) {
c0100a72:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a75:	0f b6 00             	movzbl (%eax),%eax
c0100a78:	84 c0                	test   %al,%al
c0100a7a:	74 8c                	je     c0100a08 <parse+0x1b>
c0100a7c:	8b 45 08             	mov    0x8(%ebp),%eax
c0100a7f:	0f b6 00             	movzbl (%eax),%eax
c0100a82:	0f be c0             	movsbl %al,%eax
c0100a85:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100a89:	c7 04 24 88 a2 10 c0 	movl   $0xc010a288,(%esp)
c0100a90:	e8 93 92 00 00       	call   c0109d28 <strchr>
c0100a95:	85 c0                	test   %eax,%eax
c0100a97:	74 d6                	je     c0100a6f <parse+0x82>
        while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) {
c0100a99:	e9 6a ff ff ff       	jmp    c0100a08 <parse+0x1b>
            break;
c0100a9e:	90                   	nop
        }
    }
    return argc;
c0100a9f:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0100aa2:	89 ec                	mov    %ebp,%esp
c0100aa4:	5d                   	pop    %ebp
c0100aa5:	c3                   	ret    

c0100aa6 <runcmd>:
/* *
 * runcmd - parse the input string, split it into separated arguments
 * and then lookup and invoke some related commands/
 * */
static int
runcmd(char *buf, struct trapframe *tf) {
c0100aa6:	55                   	push   %ebp
c0100aa7:	89 e5                	mov    %esp,%ebp
c0100aa9:	83 ec 68             	sub    $0x68,%esp
c0100aac:	89 5d fc             	mov    %ebx,-0x4(%ebp)
    char *argv[MAXARGS];
    int argc = parse(buf, argv);
c0100aaf:	8d 45 b0             	lea    -0x50(%ebp),%eax
c0100ab2:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100ab6:	8b 45 08             	mov    0x8(%ebp),%eax
c0100ab9:	89 04 24             	mov    %eax,(%esp)
c0100abc:	e8 2c ff ff ff       	call   c01009ed <parse>
c0100ac1:	89 45 f0             	mov    %eax,-0x10(%ebp)
    if (argc == 0) {
c0100ac4:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0100ac8:	75 0a                	jne    c0100ad4 <runcmd+0x2e>
        return 0;
c0100aca:	b8 00 00 00 00       	mov    $0x0,%eax
c0100acf:	e9 83 00 00 00       	jmp    c0100b57 <runcmd+0xb1>
    }
    int i;
    for (i = 0; i < NCOMMANDS; i ++) {
c0100ad4:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0100adb:	eb 5a                	jmp    c0100b37 <runcmd+0x91>
        if (strcmp(commands[i].name, argv[0]) == 0) {
c0100add:	8b 55 b0             	mov    -0x50(%ebp),%edx
c0100ae0:	8b 4d f4             	mov    -0xc(%ebp),%ecx
c0100ae3:	89 c8                	mov    %ecx,%eax
c0100ae5:	01 c0                	add    %eax,%eax
c0100ae7:	01 c8                	add    %ecx,%eax
c0100ae9:	c1 e0 02             	shl    $0x2,%eax
c0100aec:	05 00 80 12 c0       	add    $0xc0128000,%eax
c0100af1:	8b 00                	mov    (%eax),%eax
c0100af3:	89 54 24 04          	mov    %edx,0x4(%esp)
c0100af7:	89 04 24             	mov    %eax,(%esp)
c0100afa:	e8 8d 91 00 00       	call   c0109c8c <strcmp>
c0100aff:	85 c0                	test   %eax,%eax
c0100b01:	75 31                	jne    c0100b34 <runcmd+0x8e>
            return commands[i].func(argc - 1, argv + 1, tf);
c0100b03:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0100b06:	89 d0                	mov    %edx,%eax
c0100b08:	01 c0                	add    %eax,%eax
c0100b0a:	01 d0                	add    %edx,%eax
c0100b0c:	c1 e0 02             	shl    $0x2,%eax
c0100b0f:	05 08 80 12 c0       	add    $0xc0128008,%eax
c0100b14:	8b 10                	mov    (%eax),%edx
c0100b16:	8d 45 b0             	lea    -0x50(%ebp),%eax
c0100b19:	83 c0 04             	add    $0x4,%eax
c0100b1c:	8b 4d f0             	mov    -0x10(%ebp),%ecx
c0100b1f:	8d 59 ff             	lea    -0x1(%ecx),%ebx
c0100b22:	8b 4d 0c             	mov    0xc(%ebp),%ecx
c0100b25:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0100b29:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100b2d:	89 1c 24             	mov    %ebx,(%esp)
c0100b30:	ff d2                	call   *%edx
c0100b32:	eb 23                	jmp    c0100b57 <runcmd+0xb1>
    for (i = 0; i < NCOMMANDS; i ++) {
c0100b34:	ff 45 f4             	incl   -0xc(%ebp)
c0100b37:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100b3a:	83 f8 02             	cmp    $0x2,%eax
c0100b3d:	76 9e                	jbe    c0100add <runcmd+0x37>
        }
    }
    cprintf("Unknown command '%s'\n", argv[0]);
c0100b3f:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0100b42:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100b46:	c7 04 24 ab a2 10 c0 	movl   $0xc010a2ab,(%esp)
c0100b4d:	e8 26 f8 ff ff       	call   c0100378 <cprintf>
    return 0;
c0100b52:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100b57:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c0100b5a:	89 ec                	mov    %ebp,%esp
c0100b5c:	5d                   	pop    %ebp
c0100b5d:	c3                   	ret    

c0100b5e <kmonitor>:

/***** Implementations of basic kernel monitor commands *****/

void
kmonitor(struct trapframe *tf) {
c0100b5e:	55                   	push   %ebp
c0100b5f:	89 e5                	mov    %esp,%ebp
c0100b61:	83 ec 28             	sub    $0x28,%esp
    cprintf("Welcome to the kernel debug monitor!!\n");
c0100b64:	c7 04 24 c4 a2 10 c0 	movl   $0xc010a2c4,(%esp)
c0100b6b:	e8 08 f8 ff ff       	call   c0100378 <cprintf>
    cprintf("Type 'help' for a list of commands.\n");
c0100b70:	c7 04 24 ec a2 10 c0 	movl   $0xc010a2ec,(%esp)
c0100b77:	e8 fc f7 ff ff       	call   c0100378 <cprintf>

    if (tf != NULL) {
c0100b7c:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0100b80:	74 0b                	je     c0100b8d <kmonitor+0x2f>
        print_trapframe(tf);
c0100b82:	8b 45 08             	mov    0x8(%ebp),%eax
c0100b85:	89 04 24             	mov    %eax,(%esp)
c0100b88:	e8 2c 17 00 00       	call   c01022b9 <print_trapframe>
    }

    char *buf;
    while (1) {
        if ((buf = readline("K> ")) != NULL) {
c0100b8d:	c7 04 24 11 a3 10 c0 	movl   $0xc010a311,(%esp)
c0100b94:	e8 d0 f6 ff ff       	call   c0100269 <readline>
c0100b99:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0100b9c:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0100ba0:	74 eb                	je     c0100b8d <kmonitor+0x2f>
            if (runcmd(buf, tf) < 0) {
c0100ba2:	8b 45 08             	mov    0x8(%ebp),%eax
c0100ba5:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100ba9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100bac:	89 04 24             	mov    %eax,(%esp)
c0100baf:	e8 f2 fe ff ff       	call   c0100aa6 <runcmd>
c0100bb4:	85 c0                	test   %eax,%eax
c0100bb6:	78 02                	js     c0100bba <kmonitor+0x5c>
        if ((buf = readline("K> ")) != NULL) {
c0100bb8:	eb d3                	jmp    c0100b8d <kmonitor+0x2f>
                break;
c0100bba:	90                   	nop
            }
        }
    }
}
c0100bbb:	90                   	nop
c0100bbc:	89 ec                	mov    %ebp,%esp
c0100bbe:	5d                   	pop    %ebp
c0100bbf:	c3                   	ret    

c0100bc0 <mon_help>:

/* mon_help - print the information about mon_* functions */
int
mon_help(int argc, char **argv, struct trapframe *tf) {
c0100bc0:	55                   	push   %ebp
c0100bc1:	89 e5                	mov    %esp,%ebp
c0100bc3:	83 ec 28             	sub    $0x28,%esp
    int i;
    for (i = 0; i < NCOMMANDS; i ++) {
c0100bc6:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0100bcd:	eb 3d                	jmp    c0100c0c <mon_help+0x4c>
        cprintf("%s - %s\n", commands[i].name, commands[i].desc);
c0100bcf:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0100bd2:	89 d0                	mov    %edx,%eax
c0100bd4:	01 c0                	add    %eax,%eax
c0100bd6:	01 d0                	add    %edx,%eax
c0100bd8:	c1 e0 02             	shl    $0x2,%eax
c0100bdb:	05 04 80 12 c0       	add    $0xc0128004,%eax
c0100be0:	8b 10                	mov    (%eax),%edx
c0100be2:	8b 4d f4             	mov    -0xc(%ebp),%ecx
c0100be5:	89 c8                	mov    %ecx,%eax
c0100be7:	01 c0                	add    %eax,%eax
c0100be9:	01 c8                	add    %ecx,%eax
c0100beb:	c1 e0 02             	shl    $0x2,%eax
c0100bee:	05 00 80 12 c0       	add    $0xc0128000,%eax
c0100bf3:	8b 00                	mov    (%eax),%eax
c0100bf5:	89 54 24 08          	mov    %edx,0x8(%esp)
c0100bf9:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100bfd:	c7 04 24 15 a3 10 c0 	movl   $0xc010a315,(%esp)
c0100c04:	e8 6f f7 ff ff       	call   c0100378 <cprintf>
    for (i = 0; i < NCOMMANDS; i ++) {
c0100c09:	ff 45 f4             	incl   -0xc(%ebp)
c0100c0c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100c0f:	83 f8 02             	cmp    $0x2,%eax
c0100c12:	76 bb                	jbe    c0100bcf <mon_help+0xf>
    }
    return 0;
c0100c14:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100c19:	89 ec                	mov    %ebp,%esp
c0100c1b:	5d                   	pop    %ebp
c0100c1c:	c3                   	ret    

c0100c1d <mon_kerninfo>:
/* *
 * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to
 * print the memory occupancy in kernel.
 * */
int
mon_kerninfo(int argc, char **argv, struct trapframe *tf) {
c0100c1d:	55                   	push   %ebp
c0100c1e:	89 e5                	mov    %esp,%ebp
c0100c20:	83 ec 08             	sub    $0x8,%esp
    print_kerninfo();
c0100c23:	e8 73 fc ff ff       	call   c010089b <print_kerninfo>
    return 0;
c0100c28:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100c2d:	89 ec                	mov    %ebp,%esp
c0100c2f:	5d                   	pop    %ebp
c0100c30:	c3                   	ret    

c0100c31 <mon_backtrace>:
/* *
 * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to
 * print a backtrace of the stack.
 * */
int
mon_backtrace(int argc, char **argv, struct trapframe *tf) {
c0100c31:	55                   	push   %ebp
c0100c32:	89 e5                	mov    %esp,%ebp
c0100c34:	83 ec 08             	sub    $0x8,%esp
    print_stackframe();
c0100c37:	e8 ab fd ff ff       	call   c01009e7 <print_stackframe>
    return 0;
c0100c3c:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100c41:	89 ec                	mov    %ebp,%esp
c0100c43:	5d                   	pop    %ebp
c0100c44:	c3                   	ret    

c0100c45 <__panic>:
/* *
 * __panic - __panic is called on unresolvable fatal errors. it prints
 * "panic: 'message'", and then enters the kernel monitor.
 * */
void
__panic(const char *file, int line, const char *fmt, ...) {
c0100c45:	55                   	push   %ebp
c0100c46:	89 e5                	mov    %esp,%ebp
c0100c48:	83 ec 28             	sub    $0x28,%esp
    if (is_panic) {
c0100c4b:	a1 20 b4 12 c0       	mov    0xc012b420,%eax
c0100c50:	85 c0                	test   %eax,%eax
c0100c52:	75 5b                	jne    c0100caf <__panic+0x6a>
        goto panic_dead;
    }
    is_panic = 1;
c0100c54:	c7 05 20 b4 12 c0 01 	movl   $0x1,0xc012b420
c0100c5b:	00 00 00 

    // print the 'message'
    va_list ap;
    va_start(ap, fmt);
c0100c5e:	8d 45 14             	lea    0x14(%ebp),%eax
c0100c61:	89 45 f4             	mov    %eax,-0xc(%ebp)
    cprintf("kernel panic at %s:%d:\n    ", file, line);
c0100c64:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100c67:	89 44 24 08          	mov    %eax,0x8(%esp)
c0100c6b:	8b 45 08             	mov    0x8(%ebp),%eax
c0100c6e:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100c72:	c7 04 24 1e a3 10 c0 	movl   $0xc010a31e,(%esp)
c0100c79:	e8 fa f6 ff ff       	call   c0100378 <cprintf>
    vcprintf(fmt, ap);
c0100c7e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100c81:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100c85:	8b 45 10             	mov    0x10(%ebp),%eax
c0100c88:	89 04 24             	mov    %eax,(%esp)
c0100c8b:	e8 b3 f6 ff ff       	call   c0100343 <vcprintf>
    cprintf("\n");
c0100c90:	c7 04 24 3a a3 10 c0 	movl   $0xc010a33a,(%esp)
c0100c97:	e8 dc f6 ff ff       	call   c0100378 <cprintf>
    
    cprintf("stack trackback:\n");
c0100c9c:	c7 04 24 3c a3 10 c0 	movl   $0xc010a33c,(%esp)
c0100ca3:	e8 d0 f6 ff ff       	call   c0100378 <cprintf>
    print_stackframe();
c0100ca8:	e8 3a fd ff ff       	call   c01009e7 <print_stackframe>
c0100cad:	eb 01                	jmp    c0100cb0 <__panic+0x6b>
        goto panic_dead;
c0100caf:	90                   	nop
    
    va_end(ap);

panic_dead:
    intr_disable();
c0100cb0:	e8 46 12 00 00       	call   c0101efb <intr_disable>
    while (1) {
        kmonitor(NULL);
c0100cb5:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c0100cbc:	e8 9d fe ff ff       	call   c0100b5e <kmonitor>
c0100cc1:	eb f2                	jmp    c0100cb5 <__panic+0x70>

c0100cc3 <__warn>:
    }
}

/* __warn - like panic, but don't */
void
__warn(const char *file, int line, const char *fmt, ...) {
c0100cc3:	55                   	push   %ebp
c0100cc4:	89 e5                	mov    %esp,%ebp
c0100cc6:	83 ec 28             	sub    $0x28,%esp
    va_list ap;
    va_start(ap, fmt);
c0100cc9:	8d 45 14             	lea    0x14(%ebp),%eax
c0100ccc:	89 45 f4             	mov    %eax,-0xc(%ebp)
    cprintf("kernel warning at %s:%d:\n    ", file, line);
c0100ccf:	8b 45 0c             	mov    0xc(%ebp),%eax
c0100cd2:	89 44 24 08          	mov    %eax,0x8(%esp)
c0100cd6:	8b 45 08             	mov    0x8(%ebp),%eax
c0100cd9:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100cdd:	c7 04 24 4e a3 10 c0 	movl   $0xc010a34e,(%esp)
c0100ce4:	e8 8f f6 ff ff       	call   c0100378 <cprintf>
    vcprintf(fmt, ap);
c0100ce9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100cec:	89 44 24 04          	mov    %eax,0x4(%esp)
c0100cf0:	8b 45 10             	mov    0x10(%ebp),%eax
c0100cf3:	89 04 24             	mov    %eax,(%esp)
c0100cf6:	e8 48 f6 ff ff       	call   c0100343 <vcprintf>
    cprintf("\n");
c0100cfb:	c7 04 24 3a a3 10 c0 	movl   $0xc010a33a,(%esp)
c0100d02:	e8 71 f6 ff ff       	call   c0100378 <cprintf>
    va_end(ap);
}
c0100d07:	90                   	nop
c0100d08:	89 ec                	mov    %ebp,%esp
c0100d0a:	5d                   	pop    %ebp
c0100d0b:	c3                   	ret    

c0100d0c <is_kernel_panic>:

bool
is_kernel_panic(void) {
c0100d0c:	55                   	push   %ebp
c0100d0d:	89 e5                	mov    %esp,%ebp
    return is_panic;
c0100d0f:	a1 20 b4 12 c0       	mov    0xc012b420,%eax
}
c0100d14:	5d                   	pop    %ebp
c0100d15:	c3                   	ret    

c0100d16 <clock_init>:
/* *
 * clock_init - initialize 8253 clock to interrupt 100 times per second,
 * and then enable IRQ_TIMER.
 * */
void
clock_init(void) {
c0100d16:	55                   	push   %ebp
c0100d17:	89 e5                	mov    %esp,%ebp
c0100d19:	83 ec 28             	sub    $0x28,%esp
c0100d1c:	66 c7 45 ee 43 00    	movw   $0x43,-0x12(%ebp)
c0100d22:	c6 45 ed 34          	movb   $0x34,-0x13(%ebp)
        : "memory", "cc");
}

static inline void
outb(uint16_t port, uint8_t data) {
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100d26:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0100d2a:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0100d2e:	ee                   	out    %al,(%dx)
}
c0100d2f:	90                   	nop
c0100d30:	66 c7 45 f2 40 00    	movw   $0x40,-0xe(%ebp)
c0100d36:	c6 45 f1 9c          	movb   $0x9c,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100d3a:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c0100d3e:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0100d42:	ee                   	out    %al,(%dx)
}
c0100d43:	90                   	nop
c0100d44:	66 c7 45 f6 40 00    	movw   $0x40,-0xa(%ebp)
c0100d4a:	c6 45 f5 2e          	movb   $0x2e,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100d4e:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c0100d52:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0100d56:	ee                   	out    %al,(%dx)
}
c0100d57:	90                   	nop
    outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
    outb(IO_TIMER1, TIMER_DIV(100) % 256);
    outb(IO_TIMER1, TIMER_DIV(100) / 256);

    // initialize time counter 'ticks' to zero
    ticks = 0;
c0100d58:	c7 05 24 b4 12 c0 00 	movl   $0x0,0xc012b424
c0100d5f:	00 00 00 

    cprintf("++ setup timer interrupts\n");
c0100d62:	c7 04 24 6c a3 10 c0 	movl   $0xc010a36c,(%esp)
c0100d69:	e8 0a f6 ff ff       	call   c0100378 <cprintf>
    pic_enable(IRQ_TIMER);
c0100d6e:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c0100d75:	e8 e6 11 00 00       	call   c0101f60 <pic_enable>
}
c0100d7a:	90                   	nop
c0100d7b:	89 ec                	mov    %ebp,%esp
c0100d7d:	5d                   	pop    %ebp
c0100d7e:	c3                   	ret    

c0100d7f <__intr_save>:
#include <x86.h>
#include <intr.h>
#include <mmu.h>

static inline bool
__intr_save(void) {
c0100d7f:	55                   	push   %ebp
c0100d80:	89 e5                	mov    %esp,%ebp
c0100d82:	83 ec 18             	sub    $0x18,%esp
}

static inline uint32_t
read_eflags(void) {
    uint32_t eflags;
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c0100d85:	9c                   	pushf  
c0100d86:	58                   	pop    %eax
c0100d87:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c0100d8a:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c0100d8d:	25 00 02 00 00       	and    $0x200,%eax
c0100d92:	85 c0                	test   %eax,%eax
c0100d94:	74 0c                	je     c0100da2 <__intr_save+0x23>
        intr_disable();
c0100d96:	e8 60 11 00 00       	call   c0101efb <intr_disable>
        return 1;
c0100d9b:	b8 01 00 00 00       	mov    $0x1,%eax
c0100da0:	eb 05                	jmp    c0100da7 <__intr_save+0x28>
    }
    return 0;
c0100da2:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0100da7:	89 ec                	mov    %ebp,%esp
c0100da9:	5d                   	pop    %ebp
c0100daa:	c3                   	ret    

c0100dab <__intr_restore>:

static inline void
__intr_restore(bool flag) {
c0100dab:	55                   	push   %ebp
c0100dac:	89 e5                	mov    %esp,%ebp
c0100dae:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c0100db1:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0100db5:	74 05                	je     c0100dbc <__intr_restore+0x11>
        intr_enable();
c0100db7:	e8 37 11 00 00       	call   c0101ef3 <intr_enable>
    }
}
c0100dbc:	90                   	nop
c0100dbd:	89 ec                	mov    %ebp,%esp
c0100dbf:	5d                   	pop    %ebp
c0100dc0:	c3                   	ret    

c0100dc1 <delay>:
#include <memlayout.h>
#include <sync.h>

/* stupid I/O delay routine necessitated by historical PC design flaws */
static void
delay(void) {
c0100dc1:	55                   	push   %ebp
c0100dc2:	89 e5                	mov    %esp,%ebp
c0100dc4:	83 ec 10             	sub    $0x10,%esp
c0100dc7:	66 c7 45 f2 84 00    	movw   $0x84,-0xe(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0100dcd:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0100dd1:	89 c2                	mov    %eax,%edx
c0100dd3:	ec                   	in     (%dx),%al
c0100dd4:	88 45 f1             	mov    %al,-0xf(%ebp)
c0100dd7:	66 c7 45 f6 84 00    	movw   $0x84,-0xa(%ebp)
c0100ddd:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0100de1:	89 c2                	mov    %eax,%edx
c0100de3:	ec                   	in     (%dx),%al
c0100de4:	88 45 f5             	mov    %al,-0xb(%ebp)
c0100de7:	66 c7 45 fa 84 00    	movw   $0x84,-0x6(%ebp)
c0100ded:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c0100df1:	89 c2                	mov    %eax,%edx
c0100df3:	ec                   	in     (%dx),%al
c0100df4:	88 45 f9             	mov    %al,-0x7(%ebp)
c0100df7:	66 c7 45 fe 84 00    	movw   $0x84,-0x2(%ebp)
c0100dfd:	0f b7 45 fe          	movzwl -0x2(%ebp),%eax
c0100e01:	89 c2                	mov    %eax,%edx
c0100e03:	ec                   	in     (%dx),%al
c0100e04:	88 45 fd             	mov    %al,-0x3(%ebp)
    inb(0x84);
    inb(0x84);
    inb(0x84);
    inb(0x84);
}
c0100e07:	90                   	nop
c0100e08:	89 ec                	mov    %ebp,%esp
c0100e0a:	5d                   	pop    %ebp
c0100e0b:	c3                   	ret    

c0100e0c <cga_init>:
static uint16_t addr_6845;

/* TEXT-mode CGA/VGA display output */

static void
cga_init(void) {
c0100e0c:	55                   	push   %ebp
c0100e0d:	89 e5                	mov    %esp,%ebp
c0100e0f:	83 ec 20             	sub    $0x20,%esp
    volatile uint16_t *cp = (uint16_t *)(CGA_BUF + KERNBASE);
c0100e12:	c7 45 fc 00 80 0b c0 	movl   $0xc00b8000,-0x4(%ebp)
    uint16_t was = *cp;
c0100e19:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100e1c:	0f b7 00             	movzwl (%eax),%eax
c0100e1f:	66 89 45 fa          	mov    %ax,-0x6(%ebp)
    *cp = (uint16_t) 0xA55A;
c0100e23:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100e26:	66 c7 00 5a a5       	movw   $0xa55a,(%eax)
    if (*cp != 0xA55A) {
c0100e2b:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100e2e:	0f b7 00             	movzwl (%eax),%eax
c0100e31:	0f b7 c0             	movzwl %ax,%eax
c0100e34:	3d 5a a5 00 00       	cmp    $0xa55a,%eax
c0100e39:	74 12                	je     c0100e4d <cga_init+0x41>
        cp = (uint16_t*)(MONO_BUF + KERNBASE);
c0100e3b:	c7 45 fc 00 00 0b c0 	movl   $0xc00b0000,-0x4(%ebp)
        addr_6845 = MONO_BASE;
c0100e42:	66 c7 05 46 b4 12 c0 	movw   $0x3b4,0xc012b446
c0100e49:	b4 03 
c0100e4b:	eb 13                	jmp    c0100e60 <cga_init+0x54>
    } else {
        *cp = was;
c0100e4d:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100e50:	0f b7 55 fa          	movzwl -0x6(%ebp),%edx
c0100e54:	66 89 10             	mov    %dx,(%eax)
        addr_6845 = CGA_BASE;
c0100e57:	66 c7 05 46 b4 12 c0 	movw   $0x3d4,0xc012b446
c0100e5e:	d4 03 
    }

    // Extract cursor location
    uint32_t pos;
    outb(addr_6845, 14);
c0100e60:	0f b7 05 46 b4 12 c0 	movzwl 0xc012b446,%eax
c0100e67:	66 89 45 e6          	mov    %ax,-0x1a(%ebp)
c0100e6b:	c6 45 e5 0e          	movb   $0xe,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100e6f:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0100e73:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0100e77:	ee                   	out    %al,(%dx)
}
c0100e78:	90                   	nop
    pos = inb(addr_6845 + 1) << 8;
c0100e79:	0f b7 05 46 b4 12 c0 	movzwl 0xc012b446,%eax
c0100e80:	40                   	inc    %eax
c0100e81:	0f b7 c0             	movzwl %ax,%eax
c0100e84:	66 89 45 ea          	mov    %ax,-0x16(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0100e88:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0100e8c:	89 c2                	mov    %eax,%edx
c0100e8e:	ec                   	in     (%dx),%al
c0100e8f:	88 45 e9             	mov    %al,-0x17(%ebp)
    return data;
c0100e92:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0100e96:	0f b6 c0             	movzbl %al,%eax
c0100e99:	c1 e0 08             	shl    $0x8,%eax
c0100e9c:	89 45 f4             	mov    %eax,-0xc(%ebp)
    outb(addr_6845, 15);
c0100e9f:	0f b7 05 46 b4 12 c0 	movzwl 0xc012b446,%eax
c0100ea6:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0100eaa:	c6 45 ed 0f          	movb   $0xf,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100eae:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0100eb2:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0100eb6:	ee                   	out    %al,(%dx)
}
c0100eb7:	90                   	nop
    pos |= inb(addr_6845 + 1);
c0100eb8:	0f b7 05 46 b4 12 c0 	movzwl 0xc012b446,%eax
c0100ebf:	40                   	inc    %eax
c0100ec0:	0f b7 c0             	movzwl %ax,%eax
c0100ec3:	66 89 45 f2          	mov    %ax,-0xe(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0100ec7:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0100ecb:	89 c2                	mov    %eax,%edx
c0100ecd:	ec                   	in     (%dx),%al
c0100ece:	88 45 f1             	mov    %al,-0xf(%ebp)
    return data;
c0100ed1:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c0100ed5:	0f b6 c0             	movzbl %al,%eax
c0100ed8:	09 45 f4             	or     %eax,-0xc(%ebp)

    crt_buf = (uint16_t*) cp;
c0100edb:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0100ede:	a3 40 b4 12 c0       	mov    %eax,0xc012b440
    crt_pos = pos;
c0100ee3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0100ee6:	0f b7 c0             	movzwl %ax,%eax
c0100ee9:	66 a3 44 b4 12 c0    	mov    %ax,0xc012b444
}
c0100eef:	90                   	nop
c0100ef0:	89 ec                	mov    %ebp,%esp
c0100ef2:	5d                   	pop    %ebp
c0100ef3:	c3                   	ret    

c0100ef4 <serial_init>:

static bool serial_exists = 0;

static void
serial_init(void) {
c0100ef4:	55                   	push   %ebp
c0100ef5:	89 e5                	mov    %esp,%ebp
c0100ef7:	83 ec 48             	sub    $0x48,%esp
c0100efa:	66 c7 45 d2 fa 03    	movw   $0x3fa,-0x2e(%ebp)
c0100f00:	c6 45 d1 00          	movb   $0x0,-0x2f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100f04:	0f b6 45 d1          	movzbl -0x2f(%ebp),%eax
c0100f08:	0f b7 55 d2          	movzwl -0x2e(%ebp),%edx
c0100f0c:	ee                   	out    %al,(%dx)
}
c0100f0d:	90                   	nop
c0100f0e:	66 c7 45 d6 fb 03    	movw   $0x3fb,-0x2a(%ebp)
c0100f14:	c6 45 d5 80          	movb   $0x80,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100f18:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c0100f1c:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c0100f20:	ee                   	out    %al,(%dx)
}
c0100f21:	90                   	nop
c0100f22:	66 c7 45 da f8 03    	movw   $0x3f8,-0x26(%ebp)
c0100f28:	c6 45 d9 0c          	movb   $0xc,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100f2c:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c0100f30:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c0100f34:	ee                   	out    %al,(%dx)
}
c0100f35:	90                   	nop
c0100f36:	66 c7 45 de f9 03    	movw   $0x3f9,-0x22(%ebp)
c0100f3c:	c6 45 dd 00          	movb   $0x0,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100f40:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c0100f44:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c0100f48:	ee                   	out    %al,(%dx)
}
c0100f49:	90                   	nop
c0100f4a:	66 c7 45 e2 fb 03    	movw   $0x3fb,-0x1e(%ebp)
c0100f50:	c6 45 e1 03          	movb   $0x3,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100f54:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c0100f58:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c0100f5c:	ee                   	out    %al,(%dx)
}
c0100f5d:	90                   	nop
c0100f5e:	66 c7 45 e6 fc 03    	movw   $0x3fc,-0x1a(%ebp)
c0100f64:	c6 45 e5 00          	movb   $0x0,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100f68:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0100f6c:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0100f70:	ee                   	out    %al,(%dx)
}
c0100f71:	90                   	nop
c0100f72:	66 c7 45 ea f9 03    	movw   $0x3f9,-0x16(%ebp)
c0100f78:	c6 45 e9 01          	movb   $0x1,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0100f7c:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0100f80:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0100f84:	ee                   	out    %al,(%dx)
}
c0100f85:	90                   	nop
c0100f86:	66 c7 45 ee fd 03    	movw   $0x3fd,-0x12(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0100f8c:	0f b7 45 ee          	movzwl -0x12(%ebp),%eax
c0100f90:	89 c2                	mov    %eax,%edx
c0100f92:	ec                   	in     (%dx),%al
c0100f93:	88 45 ed             	mov    %al,-0x13(%ebp)
    return data;
c0100f96:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
    // Enable rcv interrupts
    outb(COM1 + COM_IER, COM_IER_RDI);

    // Clear any preexisting overrun indications and interrupts
    // Serial port doesn't exist if COM_LSR returns 0xFF
    serial_exists = (inb(COM1 + COM_LSR) != 0xFF);
c0100f9a:	3c ff                	cmp    $0xff,%al
c0100f9c:	0f 95 c0             	setne  %al
c0100f9f:	0f b6 c0             	movzbl %al,%eax
c0100fa2:	a3 48 b4 12 c0       	mov    %eax,0xc012b448
c0100fa7:	66 c7 45 f2 fa 03    	movw   $0x3fa,-0xe(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0100fad:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0100fb1:	89 c2                	mov    %eax,%edx
c0100fb3:	ec                   	in     (%dx),%al
c0100fb4:	88 45 f1             	mov    %al,-0xf(%ebp)
c0100fb7:	66 c7 45 f6 f8 03    	movw   $0x3f8,-0xa(%ebp)
c0100fbd:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0100fc1:	89 c2                	mov    %eax,%edx
c0100fc3:	ec                   	in     (%dx),%al
c0100fc4:	88 45 f5             	mov    %al,-0xb(%ebp)
    (void) inb(COM1+COM_IIR);
    (void) inb(COM1+COM_RX);

    if (serial_exists) {
c0100fc7:	a1 48 b4 12 c0       	mov    0xc012b448,%eax
c0100fcc:	85 c0                	test   %eax,%eax
c0100fce:	74 0c                	je     c0100fdc <serial_init+0xe8>
        pic_enable(IRQ_COM1);
c0100fd0:	c7 04 24 04 00 00 00 	movl   $0x4,(%esp)
c0100fd7:	e8 84 0f 00 00       	call   c0101f60 <pic_enable>
    }
}
c0100fdc:	90                   	nop
c0100fdd:	89 ec                	mov    %ebp,%esp
c0100fdf:	5d                   	pop    %ebp
c0100fe0:	c3                   	ret    

c0100fe1 <lpt_putc_sub>:

static void
lpt_putc_sub(int c) {
c0100fe1:	55                   	push   %ebp
c0100fe2:	89 e5                	mov    %esp,%ebp
c0100fe4:	83 ec 20             	sub    $0x20,%esp
    int i;
    for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) {
c0100fe7:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
c0100fee:	eb 08                	jmp    c0100ff8 <lpt_putc_sub+0x17>
        delay();
c0100ff0:	e8 cc fd ff ff       	call   c0100dc1 <delay>
    for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) {
c0100ff5:	ff 45 fc             	incl   -0x4(%ebp)
c0100ff8:	66 c7 45 fa 79 03    	movw   $0x379,-0x6(%ebp)
c0100ffe:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c0101002:	89 c2                	mov    %eax,%edx
c0101004:	ec                   	in     (%dx),%al
c0101005:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c0101008:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c010100c:	84 c0                	test   %al,%al
c010100e:	78 09                	js     c0101019 <lpt_putc_sub+0x38>
c0101010:	81 7d fc ff 31 00 00 	cmpl   $0x31ff,-0x4(%ebp)
c0101017:	7e d7                	jle    c0100ff0 <lpt_putc_sub+0xf>
    }
    outb(LPTPORT + 0, c);
c0101019:	8b 45 08             	mov    0x8(%ebp),%eax
c010101c:	0f b6 c0             	movzbl %al,%eax
c010101f:	66 c7 45 ee 78 03    	movw   $0x378,-0x12(%ebp)
c0101025:	88 45 ed             	mov    %al,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101028:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c010102c:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0101030:	ee                   	out    %al,(%dx)
}
c0101031:	90                   	nop
c0101032:	66 c7 45 f2 7a 03    	movw   $0x37a,-0xe(%ebp)
c0101038:	c6 45 f1 0d          	movb   $0xd,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010103c:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c0101040:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101044:	ee                   	out    %al,(%dx)
}
c0101045:	90                   	nop
c0101046:	66 c7 45 f6 7a 03    	movw   $0x37a,-0xa(%ebp)
c010104c:	c6 45 f5 08          	movb   $0x8,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101050:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c0101054:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101058:	ee                   	out    %al,(%dx)
}
c0101059:	90                   	nop
    outb(LPTPORT + 2, 0x08 | 0x04 | 0x01);
    outb(LPTPORT + 2, 0x08);
}
c010105a:	90                   	nop
c010105b:	89 ec                	mov    %ebp,%esp
c010105d:	5d                   	pop    %ebp
c010105e:	c3                   	ret    

c010105f <lpt_putc>:

/* lpt_putc - copy console output to parallel port */
static void
lpt_putc(int c) {
c010105f:	55                   	push   %ebp
c0101060:	89 e5                	mov    %esp,%ebp
c0101062:	83 ec 04             	sub    $0x4,%esp
    if (c != '\b') {
c0101065:	83 7d 08 08          	cmpl   $0x8,0x8(%ebp)
c0101069:	74 0d                	je     c0101078 <lpt_putc+0x19>
        lpt_putc_sub(c);
c010106b:	8b 45 08             	mov    0x8(%ebp),%eax
c010106e:	89 04 24             	mov    %eax,(%esp)
c0101071:	e8 6b ff ff ff       	call   c0100fe1 <lpt_putc_sub>
    else {
        lpt_putc_sub('\b');
        lpt_putc_sub(' ');
        lpt_putc_sub('\b');
    }
}
c0101076:	eb 24                	jmp    c010109c <lpt_putc+0x3d>
        lpt_putc_sub('\b');
c0101078:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c010107f:	e8 5d ff ff ff       	call   c0100fe1 <lpt_putc_sub>
        lpt_putc_sub(' ');
c0101084:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
c010108b:	e8 51 ff ff ff       	call   c0100fe1 <lpt_putc_sub>
        lpt_putc_sub('\b');
c0101090:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c0101097:	e8 45 ff ff ff       	call   c0100fe1 <lpt_putc_sub>
}
c010109c:	90                   	nop
c010109d:	89 ec                	mov    %ebp,%esp
c010109f:	5d                   	pop    %ebp
c01010a0:	c3                   	ret    

c01010a1 <cga_putc>:

/* cga_putc - print character to console */
static void
cga_putc(int c) {
c01010a1:	55                   	push   %ebp
c01010a2:	89 e5                	mov    %esp,%ebp
c01010a4:	83 ec 38             	sub    $0x38,%esp
c01010a7:	89 5d fc             	mov    %ebx,-0x4(%ebp)
    // set black on white
    if (!(c & ~0xFF)) {
c01010aa:	8b 45 08             	mov    0x8(%ebp),%eax
c01010ad:	25 00 ff ff ff       	and    $0xffffff00,%eax
c01010b2:	85 c0                	test   %eax,%eax
c01010b4:	75 07                	jne    c01010bd <cga_putc+0x1c>
        c |= 0x0700;
c01010b6:	81 4d 08 00 07 00 00 	orl    $0x700,0x8(%ebp)
    }

    switch (c & 0xff) {
c01010bd:	8b 45 08             	mov    0x8(%ebp),%eax
c01010c0:	0f b6 c0             	movzbl %al,%eax
c01010c3:	83 f8 0d             	cmp    $0xd,%eax
c01010c6:	74 72                	je     c010113a <cga_putc+0x99>
c01010c8:	83 f8 0d             	cmp    $0xd,%eax
c01010cb:	0f 8f a3 00 00 00    	jg     c0101174 <cga_putc+0xd3>
c01010d1:	83 f8 08             	cmp    $0x8,%eax
c01010d4:	74 0a                	je     c01010e0 <cga_putc+0x3f>
c01010d6:	83 f8 0a             	cmp    $0xa,%eax
c01010d9:	74 4c                	je     c0101127 <cga_putc+0x86>
c01010db:	e9 94 00 00 00       	jmp    c0101174 <cga_putc+0xd3>
    case '\b':
        if (crt_pos > 0) {
c01010e0:	0f b7 05 44 b4 12 c0 	movzwl 0xc012b444,%eax
c01010e7:	85 c0                	test   %eax,%eax
c01010e9:	0f 84 af 00 00 00    	je     c010119e <cga_putc+0xfd>
            crt_pos --;
c01010ef:	0f b7 05 44 b4 12 c0 	movzwl 0xc012b444,%eax
c01010f6:	48                   	dec    %eax
c01010f7:	0f b7 c0             	movzwl %ax,%eax
c01010fa:	66 a3 44 b4 12 c0    	mov    %ax,0xc012b444
            crt_buf[crt_pos] = (c & ~0xff) | ' ';
c0101100:	8b 45 08             	mov    0x8(%ebp),%eax
c0101103:	98                   	cwtl   
c0101104:	25 00 ff ff ff       	and    $0xffffff00,%eax
c0101109:	98                   	cwtl   
c010110a:	83 c8 20             	or     $0x20,%eax
c010110d:	98                   	cwtl   
c010110e:	8b 0d 40 b4 12 c0    	mov    0xc012b440,%ecx
c0101114:	0f b7 15 44 b4 12 c0 	movzwl 0xc012b444,%edx
c010111b:	01 d2                	add    %edx,%edx
c010111d:	01 ca                	add    %ecx,%edx
c010111f:	0f b7 c0             	movzwl %ax,%eax
c0101122:	66 89 02             	mov    %ax,(%edx)
        }
        break;
c0101125:	eb 77                	jmp    c010119e <cga_putc+0xfd>
    case '\n':
        crt_pos += CRT_COLS;
c0101127:	0f b7 05 44 b4 12 c0 	movzwl 0xc012b444,%eax
c010112e:	83 c0 50             	add    $0x50,%eax
c0101131:	0f b7 c0             	movzwl %ax,%eax
c0101134:	66 a3 44 b4 12 c0    	mov    %ax,0xc012b444
    case '\r':
        crt_pos -= (crt_pos % CRT_COLS);
c010113a:	0f b7 1d 44 b4 12 c0 	movzwl 0xc012b444,%ebx
c0101141:	0f b7 0d 44 b4 12 c0 	movzwl 0xc012b444,%ecx
c0101148:	ba cd cc cc cc       	mov    $0xcccccccd,%edx
c010114d:	89 c8                	mov    %ecx,%eax
c010114f:	f7 e2                	mul    %edx
c0101151:	c1 ea 06             	shr    $0x6,%edx
c0101154:	89 d0                	mov    %edx,%eax
c0101156:	c1 e0 02             	shl    $0x2,%eax
c0101159:	01 d0                	add    %edx,%eax
c010115b:	c1 e0 04             	shl    $0x4,%eax
c010115e:	29 c1                	sub    %eax,%ecx
c0101160:	89 ca                	mov    %ecx,%edx
c0101162:	0f b7 d2             	movzwl %dx,%edx
c0101165:	89 d8                	mov    %ebx,%eax
c0101167:	29 d0                	sub    %edx,%eax
c0101169:	0f b7 c0             	movzwl %ax,%eax
c010116c:	66 a3 44 b4 12 c0    	mov    %ax,0xc012b444
        break;
c0101172:	eb 2b                	jmp    c010119f <cga_putc+0xfe>
    default:
        crt_buf[crt_pos ++] = c;     // write the character
c0101174:	8b 0d 40 b4 12 c0    	mov    0xc012b440,%ecx
c010117a:	0f b7 05 44 b4 12 c0 	movzwl 0xc012b444,%eax
c0101181:	8d 50 01             	lea    0x1(%eax),%edx
c0101184:	0f b7 d2             	movzwl %dx,%edx
c0101187:	66 89 15 44 b4 12 c0 	mov    %dx,0xc012b444
c010118e:	01 c0                	add    %eax,%eax
c0101190:	8d 14 01             	lea    (%ecx,%eax,1),%edx
c0101193:	8b 45 08             	mov    0x8(%ebp),%eax
c0101196:	0f b7 c0             	movzwl %ax,%eax
c0101199:	66 89 02             	mov    %ax,(%edx)
        break;
c010119c:	eb 01                	jmp    c010119f <cga_putc+0xfe>
        break;
c010119e:	90                   	nop
    }

    // What is the purpose of this?
    if (crt_pos >= CRT_SIZE) {
c010119f:	0f b7 05 44 b4 12 c0 	movzwl 0xc012b444,%eax
c01011a6:	3d cf 07 00 00       	cmp    $0x7cf,%eax
c01011ab:	76 5e                	jbe    c010120b <cga_putc+0x16a>
        int i;
        memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t));
c01011ad:	a1 40 b4 12 c0       	mov    0xc012b440,%eax
c01011b2:	8d 90 a0 00 00 00    	lea    0xa0(%eax),%edx
c01011b8:	a1 40 b4 12 c0       	mov    0xc012b440,%eax
c01011bd:	c7 44 24 08 00 0f 00 	movl   $0xf00,0x8(%esp)
c01011c4:	00 
c01011c5:	89 54 24 04          	mov    %edx,0x4(%esp)
c01011c9:	89 04 24             	mov    %eax,(%esp)
c01011cc:	e8 55 8d 00 00       	call   c0109f26 <memmove>
        for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) {
c01011d1:	c7 45 f4 80 07 00 00 	movl   $0x780,-0xc(%ebp)
c01011d8:	eb 15                	jmp    c01011ef <cga_putc+0x14e>
            crt_buf[i] = 0x0700 | ' ';
c01011da:	8b 15 40 b4 12 c0    	mov    0xc012b440,%edx
c01011e0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01011e3:	01 c0                	add    %eax,%eax
c01011e5:	01 d0                	add    %edx,%eax
c01011e7:	66 c7 00 20 07       	movw   $0x720,(%eax)
        for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) {
c01011ec:	ff 45 f4             	incl   -0xc(%ebp)
c01011ef:	81 7d f4 cf 07 00 00 	cmpl   $0x7cf,-0xc(%ebp)
c01011f6:	7e e2                	jle    c01011da <cga_putc+0x139>
        }
        crt_pos -= CRT_COLS;
c01011f8:	0f b7 05 44 b4 12 c0 	movzwl 0xc012b444,%eax
c01011ff:	83 e8 50             	sub    $0x50,%eax
c0101202:	0f b7 c0             	movzwl %ax,%eax
c0101205:	66 a3 44 b4 12 c0    	mov    %ax,0xc012b444
    }

    // move that little blinky thing
    outb(addr_6845, 14);
c010120b:	0f b7 05 46 b4 12 c0 	movzwl 0xc012b446,%eax
c0101212:	66 89 45 e6          	mov    %ax,-0x1a(%ebp)
c0101216:	c6 45 e5 0e          	movb   $0xe,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010121a:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c010121e:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0101222:	ee                   	out    %al,(%dx)
}
c0101223:	90                   	nop
    outb(addr_6845 + 1, crt_pos >> 8);
c0101224:	0f b7 05 44 b4 12 c0 	movzwl 0xc012b444,%eax
c010122b:	c1 e8 08             	shr    $0x8,%eax
c010122e:	0f b7 c0             	movzwl %ax,%eax
c0101231:	0f b6 c0             	movzbl %al,%eax
c0101234:	0f b7 15 46 b4 12 c0 	movzwl 0xc012b446,%edx
c010123b:	42                   	inc    %edx
c010123c:	0f b7 d2             	movzwl %dx,%edx
c010123f:	66 89 55 ea          	mov    %dx,-0x16(%ebp)
c0101243:	88 45 e9             	mov    %al,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101246:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c010124a:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c010124e:	ee                   	out    %al,(%dx)
}
c010124f:	90                   	nop
    outb(addr_6845, 15);
c0101250:	0f b7 05 46 b4 12 c0 	movzwl 0xc012b446,%eax
c0101257:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c010125b:	c6 45 ed 0f          	movb   $0xf,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010125f:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0101263:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0101267:	ee                   	out    %al,(%dx)
}
c0101268:	90                   	nop
    outb(addr_6845 + 1, crt_pos);
c0101269:	0f b7 05 44 b4 12 c0 	movzwl 0xc012b444,%eax
c0101270:	0f b6 c0             	movzbl %al,%eax
c0101273:	0f b7 15 46 b4 12 c0 	movzwl 0xc012b446,%edx
c010127a:	42                   	inc    %edx
c010127b:	0f b7 d2             	movzwl %dx,%edx
c010127e:	66 89 55 f2          	mov    %dx,-0xe(%ebp)
c0101282:	88 45 f1             	mov    %al,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101285:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c0101289:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c010128d:	ee                   	out    %al,(%dx)
}
c010128e:	90                   	nop
}
c010128f:	90                   	nop
c0101290:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c0101293:	89 ec                	mov    %ebp,%esp
c0101295:	5d                   	pop    %ebp
c0101296:	c3                   	ret    

c0101297 <serial_putc_sub>:

static void
serial_putc_sub(int c) {
c0101297:	55                   	push   %ebp
c0101298:	89 e5                	mov    %esp,%ebp
c010129a:	83 ec 10             	sub    $0x10,%esp
    int i;
    for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) {
c010129d:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
c01012a4:	eb 08                	jmp    c01012ae <serial_putc_sub+0x17>
        delay();
c01012a6:	e8 16 fb ff ff       	call   c0100dc1 <delay>
    for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) {
c01012ab:	ff 45 fc             	incl   -0x4(%ebp)
c01012ae:	66 c7 45 fa fd 03    	movw   $0x3fd,-0x6(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c01012b4:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c01012b8:	89 c2                	mov    %eax,%edx
c01012ba:	ec                   	in     (%dx),%al
c01012bb:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c01012be:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c01012c2:	0f b6 c0             	movzbl %al,%eax
c01012c5:	83 e0 20             	and    $0x20,%eax
c01012c8:	85 c0                	test   %eax,%eax
c01012ca:	75 09                	jne    c01012d5 <serial_putc_sub+0x3e>
c01012cc:	81 7d fc ff 31 00 00 	cmpl   $0x31ff,-0x4(%ebp)
c01012d3:	7e d1                	jle    c01012a6 <serial_putc_sub+0xf>
    }
    outb(COM1 + COM_TX, c);
c01012d5:	8b 45 08             	mov    0x8(%ebp),%eax
c01012d8:	0f b6 c0             	movzbl %al,%eax
c01012db:	66 c7 45 f6 f8 03    	movw   $0x3f8,-0xa(%ebp)
c01012e1:	88 45 f5             	mov    %al,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01012e4:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c01012e8:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c01012ec:	ee                   	out    %al,(%dx)
}
c01012ed:	90                   	nop
}
c01012ee:	90                   	nop
c01012ef:	89 ec                	mov    %ebp,%esp
c01012f1:	5d                   	pop    %ebp
c01012f2:	c3                   	ret    

c01012f3 <serial_putc>:

/* serial_putc - print character to serial port */
static void
serial_putc(int c) {
c01012f3:	55                   	push   %ebp
c01012f4:	89 e5                	mov    %esp,%ebp
c01012f6:	83 ec 04             	sub    $0x4,%esp
    if (c != '\b') {
c01012f9:	83 7d 08 08          	cmpl   $0x8,0x8(%ebp)
c01012fd:	74 0d                	je     c010130c <serial_putc+0x19>
        serial_putc_sub(c);
c01012ff:	8b 45 08             	mov    0x8(%ebp),%eax
c0101302:	89 04 24             	mov    %eax,(%esp)
c0101305:	e8 8d ff ff ff       	call   c0101297 <serial_putc_sub>
    else {
        serial_putc_sub('\b');
        serial_putc_sub(' ');
        serial_putc_sub('\b');
    }
}
c010130a:	eb 24                	jmp    c0101330 <serial_putc+0x3d>
        serial_putc_sub('\b');
c010130c:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c0101313:	e8 7f ff ff ff       	call   c0101297 <serial_putc_sub>
        serial_putc_sub(' ');
c0101318:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
c010131f:	e8 73 ff ff ff       	call   c0101297 <serial_putc_sub>
        serial_putc_sub('\b');
c0101324:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
c010132b:	e8 67 ff ff ff       	call   c0101297 <serial_putc_sub>
}
c0101330:	90                   	nop
c0101331:	89 ec                	mov    %ebp,%esp
c0101333:	5d                   	pop    %ebp
c0101334:	c3                   	ret    

c0101335 <cons_intr>:
/* *
 * cons_intr - called by device interrupt routines to feed input
 * characters into the circular console input buffer.
 * */
static void
cons_intr(int (*proc)(void)) {
c0101335:	55                   	push   %ebp
c0101336:	89 e5                	mov    %esp,%ebp
c0101338:	83 ec 18             	sub    $0x18,%esp
    int c;
    while ((c = (*proc)()) != -1) {
c010133b:	eb 33                	jmp    c0101370 <cons_intr+0x3b>
        if (c != 0) {
c010133d:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0101341:	74 2d                	je     c0101370 <cons_intr+0x3b>
            cons.buf[cons.wpos ++] = c;
c0101343:	a1 64 b6 12 c0       	mov    0xc012b664,%eax
c0101348:	8d 50 01             	lea    0x1(%eax),%edx
c010134b:	89 15 64 b6 12 c0    	mov    %edx,0xc012b664
c0101351:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0101354:	88 90 60 b4 12 c0    	mov    %dl,-0x3fed4ba0(%eax)
            if (cons.wpos == CONSBUFSIZE) {
c010135a:	a1 64 b6 12 c0       	mov    0xc012b664,%eax
c010135f:	3d 00 02 00 00       	cmp    $0x200,%eax
c0101364:	75 0a                	jne    c0101370 <cons_intr+0x3b>
                cons.wpos = 0;
c0101366:	c7 05 64 b6 12 c0 00 	movl   $0x0,0xc012b664
c010136d:	00 00 00 
    while ((c = (*proc)()) != -1) {
c0101370:	8b 45 08             	mov    0x8(%ebp),%eax
c0101373:	ff d0                	call   *%eax
c0101375:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0101378:	83 7d f4 ff          	cmpl   $0xffffffff,-0xc(%ebp)
c010137c:	75 bf                	jne    c010133d <cons_intr+0x8>
            }
        }
    }
}
c010137e:	90                   	nop
c010137f:	90                   	nop
c0101380:	89 ec                	mov    %ebp,%esp
c0101382:	5d                   	pop    %ebp
c0101383:	c3                   	ret    

c0101384 <serial_proc_data>:

/* serial_proc_data - get data from serial port */
static int
serial_proc_data(void) {
c0101384:	55                   	push   %ebp
c0101385:	89 e5                	mov    %esp,%ebp
c0101387:	83 ec 10             	sub    $0x10,%esp
c010138a:	66 c7 45 fa fd 03    	movw   $0x3fd,-0x6(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101390:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c0101394:	89 c2                	mov    %eax,%edx
c0101396:	ec                   	in     (%dx),%al
c0101397:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c010139a:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
    if (!(inb(COM1 + COM_LSR) & COM_LSR_DATA)) {
c010139e:	0f b6 c0             	movzbl %al,%eax
c01013a1:	83 e0 01             	and    $0x1,%eax
c01013a4:	85 c0                	test   %eax,%eax
c01013a6:	75 07                	jne    c01013af <serial_proc_data+0x2b>
        return -1;
c01013a8:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c01013ad:	eb 2a                	jmp    c01013d9 <serial_proc_data+0x55>
c01013af:	66 c7 45 f6 f8 03    	movw   $0x3f8,-0xa(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c01013b5:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c01013b9:	89 c2                	mov    %eax,%edx
c01013bb:	ec                   	in     (%dx),%al
c01013bc:	88 45 f5             	mov    %al,-0xb(%ebp)
    return data;
c01013bf:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
    }
    int c = inb(COM1 + COM_RX);
c01013c3:	0f b6 c0             	movzbl %al,%eax
c01013c6:	89 45 fc             	mov    %eax,-0x4(%ebp)
    if (c == 127) {
c01013c9:	83 7d fc 7f          	cmpl   $0x7f,-0x4(%ebp)
c01013cd:	75 07                	jne    c01013d6 <serial_proc_data+0x52>
        c = '\b';
c01013cf:	c7 45 fc 08 00 00 00 	movl   $0x8,-0x4(%ebp)
    }
    return c;
c01013d6:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c01013d9:	89 ec                	mov    %ebp,%esp
c01013db:	5d                   	pop    %ebp
c01013dc:	c3                   	ret    

c01013dd <serial_intr>:

/* serial_intr - try to feed input characters from serial port */
void
serial_intr(void) {
c01013dd:	55                   	push   %ebp
c01013de:	89 e5                	mov    %esp,%ebp
c01013e0:	83 ec 18             	sub    $0x18,%esp
    if (serial_exists) {
c01013e3:	a1 48 b4 12 c0       	mov    0xc012b448,%eax
c01013e8:	85 c0                	test   %eax,%eax
c01013ea:	74 0c                	je     c01013f8 <serial_intr+0x1b>
        cons_intr(serial_proc_data);
c01013ec:	c7 04 24 84 13 10 c0 	movl   $0xc0101384,(%esp)
c01013f3:	e8 3d ff ff ff       	call   c0101335 <cons_intr>
    }
}
c01013f8:	90                   	nop
c01013f9:	89 ec                	mov    %ebp,%esp
c01013fb:	5d                   	pop    %ebp
c01013fc:	c3                   	ret    

c01013fd <kbd_proc_data>:
 *
 * The kbd_proc_data() function gets data from the keyboard.
 * If we finish a character, return it, else 0. And return -1 if no data.
 * */
static int
kbd_proc_data(void) {
c01013fd:	55                   	push   %ebp
c01013fe:	89 e5                	mov    %esp,%ebp
c0101400:	83 ec 38             	sub    $0x38,%esp
c0101403:	66 c7 45 f0 64 00    	movw   $0x64,-0x10(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101409:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010140c:	89 c2                	mov    %eax,%edx
c010140e:	ec                   	in     (%dx),%al
c010140f:	88 45 ef             	mov    %al,-0x11(%ebp)
    return data;
c0101412:	0f b6 45 ef          	movzbl -0x11(%ebp),%eax
    int c;
    uint8_t data;
    static uint32_t shift;

    if ((inb(KBSTATP) & KBS_DIB) == 0) {
c0101416:	0f b6 c0             	movzbl %al,%eax
c0101419:	83 e0 01             	and    $0x1,%eax
c010141c:	85 c0                	test   %eax,%eax
c010141e:	75 0a                	jne    c010142a <kbd_proc_data+0x2d>
        return -1;
c0101420:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c0101425:	e9 56 01 00 00       	jmp    c0101580 <kbd_proc_data+0x183>
c010142a:	66 c7 45 ec 60 00    	movw   $0x60,-0x14(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c0101430:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101433:	89 c2                	mov    %eax,%edx
c0101435:	ec                   	in     (%dx),%al
c0101436:	88 45 eb             	mov    %al,-0x15(%ebp)
    return data;
c0101439:	0f b6 45 eb          	movzbl -0x15(%ebp),%eax
    }

    data = inb(KBDATAP);
c010143d:	88 45 f3             	mov    %al,-0xd(%ebp)

    if (data == 0xE0) {
c0101440:	80 7d f3 e0          	cmpb   $0xe0,-0xd(%ebp)
c0101444:	75 17                	jne    c010145d <kbd_proc_data+0x60>
        // E0 escape character
        shift |= E0ESC;
c0101446:	a1 68 b6 12 c0       	mov    0xc012b668,%eax
c010144b:	83 c8 40             	or     $0x40,%eax
c010144e:	a3 68 b6 12 c0       	mov    %eax,0xc012b668
        return 0;
c0101453:	b8 00 00 00 00       	mov    $0x0,%eax
c0101458:	e9 23 01 00 00       	jmp    c0101580 <kbd_proc_data+0x183>
    } else if (data & 0x80) {
c010145d:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101461:	84 c0                	test   %al,%al
c0101463:	79 45                	jns    c01014aa <kbd_proc_data+0xad>
        // Key released
        data = (shift & E0ESC ? data : data & 0x7F);
c0101465:	a1 68 b6 12 c0       	mov    0xc012b668,%eax
c010146a:	83 e0 40             	and    $0x40,%eax
c010146d:	85 c0                	test   %eax,%eax
c010146f:	75 08                	jne    c0101479 <kbd_proc_data+0x7c>
c0101471:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101475:	24 7f                	and    $0x7f,%al
c0101477:	eb 04                	jmp    c010147d <kbd_proc_data+0x80>
c0101479:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c010147d:	88 45 f3             	mov    %al,-0xd(%ebp)
        shift &= ~(shiftcode[data] | E0ESC);
c0101480:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c0101484:	0f b6 80 40 80 12 c0 	movzbl -0x3fed7fc0(%eax),%eax
c010148b:	0c 40                	or     $0x40,%al
c010148d:	0f b6 c0             	movzbl %al,%eax
c0101490:	f7 d0                	not    %eax
c0101492:	89 c2                	mov    %eax,%edx
c0101494:	a1 68 b6 12 c0       	mov    0xc012b668,%eax
c0101499:	21 d0                	and    %edx,%eax
c010149b:	a3 68 b6 12 c0       	mov    %eax,0xc012b668
        return 0;
c01014a0:	b8 00 00 00 00       	mov    $0x0,%eax
c01014a5:	e9 d6 00 00 00       	jmp    c0101580 <kbd_proc_data+0x183>
    } else if (shift & E0ESC) {
c01014aa:	a1 68 b6 12 c0       	mov    0xc012b668,%eax
c01014af:	83 e0 40             	and    $0x40,%eax
c01014b2:	85 c0                	test   %eax,%eax
c01014b4:	74 11                	je     c01014c7 <kbd_proc_data+0xca>
        // Last character was an E0 escape; or with 0x80
        data |= 0x80;
c01014b6:	80 4d f3 80          	orb    $0x80,-0xd(%ebp)
        shift &= ~E0ESC;
c01014ba:	a1 68 b6 12 c0       	mov    0xc012b668,%eax
c01014bf:	83 e0 bf             	and    $0xffffffbf,%eax
c01014c2:	a3 68 b6 12 c0       	mov    %eax,0xc012b668
    }

    shift |= shiftcode[data];
c01014c7:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c01014cb:	0f b6 80 40 80 12 c0 	movzbl -0x3fed7fc0(%eax),%eax
c01014d2:	0f b6 d0             	movzbl %al,%edx
c01014d5:	a1 68 b6 12 c0       	mov    0xc012b668,%eax
c01014da:	09 d0                	or     %edx,%eax
c01014dc:	a3 68 b6 12 c0       	mov    %eax,0xc012b668
    shift ^= togglecode[data];
c01014e1:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c01014e5:	0f b6 80 40 81 12 c0 	movzbl -0x3fed7ec0(%eax),%eax
c01014ec:	0f b6 d0             	movzbl %al,%edx
c01014ef:	a1 68 b6 12 c0       	mov    0xc012b668,%eax
c01014f4:	31 d0                	xor    %edx,%eax
c01014f6:	a3 68 b6 12 c0       	mov    %eax,0xc012b668

    c = charcode[shift & (CTL | SHIFT)][data];
c01014fb:	a1 68 b6 12 c0       	mov    0xc012b668,%eax
c0101500:	83 e0 03             	and    $0x3,%eax
c0101503:	8b 14 85 40 85 12 c0 	mov    -0x3fed7ac0(,%eax,4),%edx
c010150a:	0f b6 45 f3          	movzbl -0xd(%ebp),%eax
c010150e:	01 d0                	add    %edx,%eax
c0101510:	0f b6 00             	movzbl (%eax),%eax
c0101513:	0f b6 c0             	movzbl %al,%eax
c0101516:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (shift & CAPSLOCK) {
c0101519:	a1 68 b6 12 c0       	mov    0xc012b668,%eax
c010151e:	83 e0 08             	and    $0x8,%eax
c0101521:	85 c0                	test   %eax,%eax
c0101523:	74 22                	je     c0101547 <kbd_proc_data+0x14a>
        if ('a' <= c && c <= 'z')
c0101525:	83 7d f4 60          	cmpl   $0x60,-0xc(%ebp)
c0101529:	7e 0c                	jle    c0101537 <kbd_proc_data+0x13a>
c010152b:	83 7d f4 7a          	cmpl   $0x7a,-0xc(%ebp)
c010152f:	7f 06                	jg     c0101537 <kbd_proc_data+0x13a>
            c += 'A' - 'a';
c0101531:	83 6d f4 20          	subl   $0x20,-0xc(%ebp)
c0101535:	eb 10                	jmp    c0101547 <kbd_proc_data+0x14a>
        else if ('A' <= c && c <= 'Z')
c0101537:	83 7d f4 40          	cmpl   $0x40,-0xc(%ebp)
c010153b:	7e 0a                	jle    c0101547 <kbd_proc_data+0x14a>
c010153d:	83 7d f4 5a          	cmpl   $0x5a,-0xc(%ebp)
c0101541:	7f 04                	jg     c0101547 <kbd_proc_data+0x14a>
            c += 'a' - 'A';
c0101543:	83 45 f4 20          	addl   $0x20,-0xc(%ebp)
    }

    // Process special keys
    // Ctrl-Alt-Del: reboot
    if (!(~shift & (CTL | ALT)) && c == KEY_DEL) {
c0101547:	a1 68 b6 12 c0       	mov    0xc012b668,%eax
c010154c:	f7 d0                	not    %eax
c010154e:	83 e0 06             	and    $0x6,%eax
c0101551:	85 c0                	test   %eax,%eax
c0101553:	75 28                	jne    c010157d <kbd_proc_data+0x180>
c0101555:	81 7d f4 e9 00 00 00 	cmpl   $0xe9,-0xc(%ebp)
c010155c:	75 1f                	jne    c010157d <kbd_proc_data+0x180>
        cprintf("Rebooting!\n");
c010155e:	c7 04 24 87 a3 10 c0 	movl   $0xc010a387,(%esp)
c0101565:	e8 0e ee ff ff       	call   c0100378 <cprintf>
c010156a:	66 c7 45 e8 92 00    	movw   $0x92,-0x18(%ebp)
c0101570:	c6 45 e7 03          	movb   $0x3,-0x19(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101574:	0f b6 45 e7          	movzbl -0x19(%ebp),%eax
c0101578:	8b 55 e8             	mov    -0x18(%ebp),%edx
c010157b:	ee                   	out    %al,(%dx)
}
c010157c:	90                   	nop
        outb(0x92, 0x3); // courtesy of Chris Frost
    }
    return c;
c010157d:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0101580:	89 ec                	mov    %ebp,%esp
c0101582:	5d                   	pop    %ebp
c0101583:	c3                   	ret    

c0101584 <kbd_intr>:

/* kbd_intr - try to feed input characters from keyboard */
static void
kbd_intr(void) {
c0101584:	55                   	push   %ebp
c0101585:	89 e5                	mov    %esp,%ebp
c0101587:	83 ec 18             	sub    $0x18,%esp
    cons_intr(kbd_proc_data);
c010158a:	c7 04 24 fd 13 10 c0 	movl   $0xc01013fd,(%esp)
c0101591:	e8 9f fd ff ff       	call   c0101335 <cons_intr>
}
c0101596:	90                   	nop
c0101597:	89 ec                	mov    %ebp,%esp
c0101599:	5d                   	pop    %ebp
c010159a:	c3                   	ret    

c010159b <kbd_init>:

static void
kbd_init(void) {
c010159b:	55                   	push   %ebp
c010159c:	89 e5                	mov    %esp,%ebp
c010159e:	83 ec 18             	sub    $0x18,%esp
    // drain the kbd buffer
    kbd_intr();
c01015a1:	e8 de ff ff ff       	call   c0101584 <kbd_intr>
    pic_enable(IRQ_KBD);
c01015a6:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01015ad:	e8 ae 09 00 00       	call   c0101f60 <pic_enable>
}
c01015b2:	90                   	nop
c01015b3:	89 ec                	mov    %ebp,%esp
c01015b5:	5d                   	pop    %ebp
c01015b6:	c3                   	ret    

c01015b7 <cons_init>:

/* cons_init - initializes the console devices */
void
cons_init(void) {
c01015b7:	55                   	push   %ebp
c01015b8:	89 e5                	mov    %esp,%ebp
c01015ba:	83 ec 18             	sub    $0x18,%esp
    cga_init();
c01015bd:	e8 4a f8 ff ff       	call   c0100e0c <cga_init>
    serial_init();
c01015c2:	e8 2d f9 ff ff       	call   c0100ef4 <serial_init>
    kbd_init();
c01015c7:	e8 cf ff ff ff       	call   c010159b <kbd_init>
    if (!serial_exists) {
c01015cc:	a1 48 b4 12 c0       	mov    0xc012b448,%eax
c01015d1:	85 c0                	test   %eax,%eax
c01015d3:	75 0c                	jne    c01015e1 <cons_init+0x2a>
        cprintf("serial port does not exist!!\n");
c01015d5:	c7 04 24 93 a3 10 c0 	movl   $0xc010a393,(%esp)
c01015dc:	e8 97 ed ff ff       	call   c0100378 <cprintf>
    }
}
c01015e1:	90                   	nop
c01015e2:	89 ec                	mov    %ebp,%esp
c01015e4:	5d                   	pop    %ebp
c01015e5:	c3                   	ret    

c01015e6 <cons_putc>:

/* cons_putc - print a single character @c to console devices */
void
cons_putc(int c) {
c01015e6:	55                   	push   %ebp
c01015e7:	89 e5                	mov    %esp,%ebp
c01015e9:	83 ec 28             	sub    $0x28,%esp
    bool intr_flag;
    local_intr_save(intr_flag);
c01015ec:	e8 8e f7 ff ff       	call   c0100d7f <__intr_save>
c01015f1:	89 45 f4             	mov    %eax,-0xc(%ebp)
    {
        lpt_putc(c);
c01015f4:	8b 45 08             	mov    0x8(%ebp),%eax
c01015f7:	89 04 24             	mov    %eax,(%esp)
c01015fa:	e8 60 fa ff ff       	call   c010105f <lpt_putc>
        cga_putc(c);
c01015ff:	8b 45 08             	mov    0x8(%ebp),%eax
c0101602:	89 04 24             	mov    %eax,(%esp)
c0101605:	e8 97 fa ff ff       	call   c01010a1 <cga_putc>
        serial_putc(c);
c010160a:	8b 45 08             	mov    0x8(%ebp),%eax
c010160d:	89 04 24             	mov    %eax,(%esp)
c0101610:	e8 de fc ff ff       	call   c01012f3 <serial_putc>
    }
    local_intr_restore(intr_flag);
c0101615:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0101618:	89 04 24             	mov    %eax,(%esp)
c010161b:	e8 8b f7 ff ff       	call   c0100dab <__intr_restore>
}
c0101620:	90                   	nop
c0101621:	89 ec                	mov    %ebp,%esp
c0101623:	5d                   	pop    %ebp
c0101624:	c3                   	ret    

c0101625 <cons_getc>:
/* *
 * cons_getc - return the next input character from console,
 * or 0 if none waiting.
 * */
int
cons_getc(void) {
c0101625:	55                   	push   %ebp
c0101626:	89 e5                	mov    %esp,%ebp
c0101628:	83 ec 28             	sub    $0x28,%esp
    int c = 0;
c010162b:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    bool intr_flag;
    local_intr_save(intr_flag);
c0101632:	e8 48 f7 ff ff       	call   c0100d7f <__intr_save>
c0101637:	89 45 f0             	mov    %eax,-0x10(%ebp)
    {
        // poll for any pending input characters,
        // so that this function works even when interrupts are disabled
        // (e.g., when called from the kernel monitor).
        serial_intr();
c010163a:	e8 9e fd ff ff       	call   c01013dd <serial_intr>
        kbd_intr();
c010163f:	e8 40 ff ff ff       	call   c0101584 <kbd_intr>

        // grab the next character from the input buffer.
        if (cons.rpos != cons.wpos) {
c0101644:	8b 15 60 b6 12 c0    	mov    0xc012b660,%edx
c010164a:	a1 64 b6 12 c0       	mov    0xc012b664,%eax
c010164f:	39 c2                	cmp    %eax,%edx
c0101651:	74 31                	je     c0101684 <cons_getc+0x5f>
            c = cons.buf[cons.rpos ++];
c0101653:	a1 60 b6 12 c0       	mov    0xc012b660,%eax
c0101658:	8d 50 01             	lea    0x1(%eax),%edx
c010165b:	89 15 60 b6 12 c0    	mov    %edx,0xc012b660
c0101661:	0f b6 80 60 b4 12 c0 	movzbl -0x3fed4ba0(%eax),%eax
c0101668:	0f b6 c0             	movzbl %al,%eax
c010166b:	89 45 f4             	mov    %eax,-0xc(%ebp)
            if (cons.rpos == CONSBUFSIZE) {
c010166e:	a1 60 b6 12 c0       	mov    0xc012b660,%eax
c0101673:	3d 00 02 00 00       	cmp    $0x200,%eax
c0101678:	75 0a                	jne    c0101684 <cons_getc+0x5f>
                cons.rpos = 0;
c010167a:	c7 05 60 b6 12 c0 00 	movl   $0x0,0xc012b660
c0101681:	00 00 00 
            }
        }
    }
    local_intr_restore(intr_flag);
c0101684:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0101687:	89 04 24             	mov    %eax,(%esp)
c010168a:	e8 1c f7 ff ff       	call   c0100dab <__intr_restore>
    return c;
c010168f:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0101692:	89 ec                	mov    %ebp,%esp
c0101694:	5d                   	pop    %ebp
c0101695:	c3                   	ret    

c0101696 <ide_wait_ready>:
    unsigned int size;          // Size in Sectors
    unsigned char model[41];    // Model in String
} ide_devices[MAX_IDE];

static int
ide_wait_ready(unsigned short iobase, bool check_error) {
c0101696:	55                   	push   %ebp
c0101697:	89 e5                	mov    %esp,%ebp
c0101699:	83 ec 14             	sub    $0x14,%esp
c010169c:	8b 45 08             	mov    0x8(%ebp),%eax
c010169f:	66 89 45 ec          	mov    %ax,-0x14(%ebp)
    int r;
    while ((r = inb(iobase + ISA_STATUS)) & IDE_BSY)
c01016a3:	90                   	nop
c01016a4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01016a7:	83 c0 07             	add    $0x7,%eax
c01016aa:	0f b7 c0             	movzwl %ax,%eax
c01016ad:	66 89 45 fa          	mov    %ax,-0x6(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c01016b1:	0f b7 45 fa          	movzwl -0x6(%ebp),%eax
c01016b5:	89 c2                	mov    %eax,%edx
c01016b7:	ec                   	in     (%dx),%al
c01016b8:	88 45 f9             	mov    %al,-0x7(%ebp)
    return data;
c01016bb:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c01016bf:	0f b6 c0             	movzbl %al,%eax
c01016c2:	89 45 fc             	mov    %eax,-0x4(%ebp)
c01016c5:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01016c8:	25 80 00 00 00       	and    $0x80,%eax
c01016cd:	85 c0                	test   %eax,%eax
c01016cf:	75 d3                	jne    c01016a4 <ide_wait_ready+0xe>
        /* nothing */;
    if (check_error && (r & (IDE_DF | IDE_ERR)) != 0) {
c01016d1:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c01016d5:	74 11                	je     c01016e8 <ide_wait_ready+0x52>
c01016d7:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01016da:	83 e0 21             	and    $0x21,%eax
c01016dd:	85 c0                	test   %eax,%eax
c01016df:	74 07                	je     c01016e8 <ide_wait_ready+0x52>
        return -1;
c01016e1:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
c01016e6:	eb 05                	jmp    c01016ed <ide_wait_ready+0x57>
    }
    return 0;
c01016e8:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01016ed:	89 ec                	mov    %ebp,%esp
c01016ef:	5d                   	pop    %ebp
c01016f0:	c3                   	ret    

c01016f1 <ide_init>:

void
ide_init(void) {
c01016f1:	55                   	push   %ebp
c01016f2:	89 e5                	mov    %esp,%ebp
c01016f4:	57                   	push   %edi
c01016f5:	53                   	push   %ebx
c01016f6:	81 ec 50 02 00 00    	sub    $0x250,%esp
    static_assert((SECTSIZE % 4) == 0);
    unsigned short ideno, iobase;
    for (ideno = 0; ideno < MAX_IDE; ideno ++) {
c01016fc:	66 c7 45 f6 00 00    	movw   $0x0,-0xa(%ebp)
c0101702:	e9 bd 02 00 00       	jmp    c01019c4 <ide_init+0x2d3>
        /* assume that no device here */
        ide_devices[ideno].valid = 0;
c0101707:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c010170b:	89 d0                	mov    %edx,%eax
c010170d:	c1 e0 03             	shl    $0x3,%eax
c0101710:	29 d0                	sub    %edx,%eax
c0101712:	c1 e0 03             	shl    $0x3,%eax
c0101715:	05 80 b6 12 c0       	add    $0xc012b680,%eax
c010171a:	c6 00 00             	movb   $0x0,(%eax)

        iobase = IO_BASE(ideno);
c010171d:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0101721:	d1 e8                	shr    %eax
c0101723:	0f b7 c0             	movzwl %ax,%eax
c0101726:	8b 04 85 b4 a3 10 c0 	mov    -0x3fef5c4c(,%eax,4),%eax
c010172d:	66 89 45 ea          	mov    %ax,-0x16(%ebp)

        /* wait device ready */
        ide_wait_ready(iobase, 0);
c0101731:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0101735:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010173c:	00 
c010173d:	89 04 24             	mov    %eax,(%esp)
c0101740:	e8 51 ff ff ff       	call   c0101696 <ide_wait_ready>

        /* step1: select drive */
        outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4));
c0101745:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c0101749:	c1 e0 04             	shl    $0x4,%eax
c010174c:	24 10                	and    $0x10,%al
c010174e:	0c e0                	or     $0xe0,%al
c0101750:	0f b6 c0             	movzbl %al,%eax
c0101753:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0101757:	83 c2 06             	add    $0x6,%edx
c010175a:	0f b7 d2             	movzwl %dx,%edx
c010175d:	66 89 55 ca          	mov    %dx,-0x36(%ebp)
c0101761:	88 45 c9             	mov    %al,-0x37(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101764:	0f b6 45 c9          	movzbl -0x37(%ebp),%eax
c0101768:	0f b7 55 ca          	movzwl -0x36(%ebp),%edx
c010176c:	ee                   	out    %al,(%dx)
}
c010176d:	90                   	nop
        ide_wait_ready(iobase, 0);
c010176e:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0101772:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0101779:	00 
c010177a:	89 04 24             	mov    %eax,(%esp)
c010177d:	e8 14 ff ff ff       	call   c0101696 <ide_wait_ready>

        /* step2: send ATA identify command */
        outb(iobase + ISA_COMMAND, IDE_CMD_IDENTIFY);
c0101782:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c0101786:	83 c0 07             	add    $0x7,%eax
c0101789:	0f b7 c0             	movzwl %ax,%eax
c010178c:	66 89 45 ce          	mov    %ax,-0x32(%ebp)
c0101790:	c6 45 cd ec          	movb   $0xec,-0x33(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101794:	0f b6 45 cd          	movzbl -0x33(%ebp),%eax
c0101798:	0f b7 55 ce          	movzwl -0x32(%ebp),%edx
c010179c:	ee                   	out    %al,(%dx)
}
c010179d:	90                   	nop
        ide_wait_ready(iobase, 0);
c010179e:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c01017a2:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01017a9:	00 
c01017aa:	89 04 24             	mov    %eax,(%esp)
c01017ad:	e8 e4 fe ff ff       	call   c0101696 <ide_wait_ready>

        /* step3: polling */
        if (inb(iobase + ISA_STATUS) == 0 || ide_wait_ready(iobase, 1) != 0) {
c01017b2:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c01017b6:	83 c0 07             	add    $0x7,%eax
c01017b9:	0f b7 c0             	movzwl %ax,%eax
c01017bc:	66 89 45 d2          	mov    %ax,-0x2e(%ebp)
    asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory");
c01017c0:	0f b7 45 d2          	movzwl -0x2e(%ebp),%eax
c01017c4:	89 c2                	mov    %eax,%edx
c01017c6:	ec                   	in     (%dx),%al
c01017c7:	88 45 d1             	mov    %al,-0x2f(%ebp)
    return data;
c01017ca:	0f b6 45 d1          	movzbl -0x2f(%ebp),%eax
c01017ce:	84 c0                	test   %al,%al
c01017d0:	0f 84 e4 01 00 00    	je     c01019ba <ide_init+0x2c9>
c01017d6:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c01017da:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01017e1:	00 
c01017e2:	89 04 24             	mov    %eax,(%esp)
c01017e5:	e8 ac fe ff ff       	call   c0101696 <ide_wait_ready>
c01017ea:	85 c0                	test   %eax,%eax
c01017ec:	0f 85 c8 01 00 00    	jne    c01019ba <ide_init+0x2c9>
            continue ;
        }

        /* device is ok */
        ide_devices[ideno].valid = 1;
c01017f2:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c01017f6:	89 d0                	mov    %edx,%eax
c01017f8:	c1 e0 03             	shl    $0x3,%eax
c01017fb:	29 d0                	sub    %edx,%eax
c01017fd:	c1 e0 03             	shl    $0x3,%eax
c0101800:	05 80 b6 12 c0       	add    $0xc012b680,%eax
c0101805:	c6 00 01             	movb   $0x1,(%eax)

        /* read identification space of the device */
        unsigned int buffer[128];
        insl(iobase + ISA_DATA, buffer, sizeof(buffer) / sizeof(unsigned int));
c0101808:	0f b7 45 ea          	movzwl -0x16(%ebp),%eax
c010180c:	89 45 c4             	mov    %eax,-0x3c(%ebp)
c010180f:	8d 85 bc fd ff ff    	lea    -0x244(%ebp),%eax
c0101815:	89 45 c0             	mov    %eax,-0x40(%ebp)
c0101818:	c7 45 bc 80 00 00 00 	movl   $0x80,-0x44(%ebp)
    asm volatile (
c010181f:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c0101822:	8b 4d c0             	mov    -0x40(%ebp),%ecx
c0101825:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0101828:	89 cb                	mov    %ecx,%ebx
c010182a:	89 df                	mov    %ebx,%edi
c010182c:	89 c1                	mov    %eax,%ecx
c010182e:	fc                   	cld    
c010182f:	f2 6d                	repnz insl (%dx),%es:(%edi)
c0101831:	89 c8                	mov    %ecx,%eax
c0101833:	89 fb                	mov    %edi,%ebx
c0101835:	89 5d c0             	mov    %ebx,-0x40(%ebp)
c0101838:	89 45 bc             	mov    %eax,-0x44(%ebp)
}
c010183b:	90                   	nop

        unsigned char *ident = (unsigned char *)buffer;
c010183c:	8d 85 bc fd ff ff    	lea    -0x244(%ebp),%eax
c0101842:	89 45 e4             	mov    %eax,-0x1c(%ebp)
        unsigned int sectors;
        unsigned int cmdsets = *(unsigned int *)(ident + IDE_IDENT_CMDSETS);
c0101845:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0101848:	8b 80 a4 00 00 00    	mov    0xa4(%eax),%eax
c010184e:	89 45 e0             	mov    %eax,-0x20(%ebp)
        /* device use 48-bits or 28-bits addressing */
        if (cmdsets & (1 << 26)) {
c0101851:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0101854:	25 00 00 00 04       	and    $0x4000000,%eax
c0101859:	85 c0                	test   %eax,%eax
c010185b:	74 0e                	je     c010186b <ide_init+0x17a>
            sectors = *(unsigned int *)(ident + IDE_IDENT_MAX_LBA_EXT);
c010185d:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0101860:	8b 80 c8 00 00 00    	mov    0xc8(%eax),%eax
c0101866:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0101869:	eb 09                	jmp    c0101874 <ide_init+0x183>
        }
        else {
            sectors = *(unsigned int *)(ident + IDE_IDENT_MAX_LBA);
c010186b:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010186e:	8b 40 78             	mov    0x78(%eax),%eax
c0101871:	89 45 f0             	mov    %eax,-0x10(%ebp)
        }
        ide_devices[ideno].sets = cmdsets;
c0101874:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101878:	89 d0                	mov    %edx,%eax
c010187a:	c1 e0 03             	shl    $0x3,%eax
c010187d:	29 d0                	sub    %edx,%eax
c010187f:	c1 e0 03             	shl    $0x3,%eax
c0101882:	8d 90 84 b6 12 c0    	lea    -0x3fed497c(%eax),%edx
c0101888:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010188b:	89 02                	mov    %eax,(%edx)
        ide_devices[ideno].size = sectors;
c010188d:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101891:	89 d0                	mov    %edx,%eax
c0101893:	c1 e0 03             	shl    $0x3,%eax
c0101896:	29 d0                	sub    %edx,%eax
c0101898:	c1 e0 03             	shl    $0x3,%eax
c010189b:	8d 90 88 b6 12 c0    	lea    -0x3fed4978(%eax),%edx
c01018a1:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01018a4:	89 02                	mov    %eax,(%edx)

        /* check if supports LBA */
        assert((*(unsigned short *)(ident + IDE_IDENT_CAPABILITIES) & 0x200) != 0);
c01018a6:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01018a9:	83 c0 62             	add    $0x62,%eax
c01018ac:	0f b7 00             	movzwl (%eax),%eax
c01018af:	25 00 02 00 00       	and    $0x200,%eax
c01018b4:	85 c0                	test   %eax,%eax
c01018b6:	75 24                	jne    c01018dc <ide_init+0x1eb>
c01018b8:	c7 44 24 0c bc a3 10 	movl   $0xc010a3bc,0xc(%esp)
c01018bf:	c0 
c01018c0:	c7 44 24 08 ff a3 10 	movl   $0xc010a3ff,0x8(%esp)
c01018c7:	c0 
c01018c8:	c7 44 24 04 7d 00 00 	movl   $0x7d,0x4(%esp)
c01018cf:	00 
c01018d0:	c7 04 24 14 a4 10 c0 	movl   $0xc010a414,(%esp)
c01018d7:	e8 69 f3 ff ff       	call   c0100c45 <__panic>

        unsigned char *model = ide_devices[ideno].model, *data = ident + IDE_IDENT_MODEL;
c01018dc:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c01018e0:	89 d0                	mov    %edx,%eax
c01018e2:	c1 e0 03             	shl    $0x3,%eax
c01018e5:	29 d0                	sub    %edx,%eax
c01018e7:	c1 e0 03             	shl    $0x3,%eax
c01018ea:	05 80 b6 12 c0       	add    $0xc012b680,%eax
c01018ef:	83 c0 0c             	add    $0xc,%eax
c01018f2:	89 45 dc             	mov    %eax,-0x24(%ebp)
c01018f5:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01018f8:	83 c0 36             	add    $0x36,%eax
c01018fb:	89 45 d8             	mov    %eax,-0x28(%ebp)
        unsigned int i, length = 40;
c01018fe:	c7 45 d4 28 00 00 00 	movl   $0x28,-0x2c(%ebp)
        for (i = 0; i < length; i += 2) {
c0101905:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c010190c:	eb 34                	jmp    c0101942 <ide_init+0x251>
            model[i] = data[i + 1], model[i + 1] = data[i];
c010190e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101911:	8d 50 01             	lea    0x1(%eax),%edx
c0101914:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0101917:	01 c2                	add    %eax,%edx
c0101919:	8b 4d dc             	mov    -0x24(%ebp),%ecx
c010191c:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010191f:	01 c8                	add    %ecx,%eax
c0101921:	0f b6 12             	movzbl (%edx),%edx
c0101924:	88 10                	mov    %dl,(%eax)
c0101926:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0101929:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010192c:	01 c2                	add    %eax,%edx
c010192e:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101931:	8d 48 01             	lea    0x1(%eax),%ecx
c0101934:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0101937:	01 c8                	add    %ecx,%eax
c0101939:	0f b6 12             	movzbl (%edx),%edx
c010193c:	88 10                	mov    %dl,(%eax)
        for (i = 0; i < length; i += 2) {
c010193e:	83 45 ec 02          	addl   $0x2,-0x14(%ebp)
c0101942:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101945:	3b 45 d4             	cmp    -0x2c(%ebp),%eax
c0101948:	72 c4                	jb     c010190e <ide_init+0x21d>
        }
        do {
            model[i] = '\0';
c010194a:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010194d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101950:	01 d0                	add    %edx,%eax
c0101952:	c6 00 00             	movb   $0x0,(%eax)
        } while (i -- > 0 && model[i] == ' ');
c0101955:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101958:	8d 50 ff             	lea    -0x1(%eax),%edx
c010195b:	89 55 ec             	mov    %edx,-0x14(%ebp)
c010195e:	85 c0                	test   %eax,%eax
c0101960:	74 0f                	je     c0101971 <ide_init+0x280>
c0101962:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0101965:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101968:	01 d0                	add    %edx,%eax
c010196a:	0f b6 00             	movzbl (%eax),%eax
c010196d:	3c 20                	cmp    $0x20,%al
c010196f:	74 d9                	je     c010194a <ide_init+0x259>

        cprintf("ide %d: %10u(sectors), '%s'.\n", ideno, ide_devices[ideno].size, ide_devices[ideno].model);
c0101971:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0101975:	89 d0                	mov    %edx,%eax
c0101977:	c1 e0 03             	shl    $0x3,%eax
c010197a:	29 d0                	sub    %edx,%eax
c010197c:	c1 e0 03             	shl    $0x3,%eax
c010197f:	05 80 b6 12 c0       	add    $0xc012b680,%eax
c0101984:	8d 48 0c             	lea    0xc(%eax),%ecx
c0101987:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c010198b:	89 d0                	mov    %edx,%eax
c010198d:	c1 e0 03             	shl    $0x3,%eax
c0101990:	29 d0                	sub    %edx,%eax
c0101992:	c1 e0 03             	shl    $0x3,%eax
c0101995:	05 88 b6 12 c0       	add    $0xc012b688,%eax
c010199a:	8b 10                	mov    (%eax),%edx
c010199c:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c01019a0:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c01019a4:	89 54 24 08          	mov    %edx,0x8(%esp)
c01019a8:	89 44 24 04          	mov    %eax,0x4(%esp)
c01019ac:	c7 04 24 26 a4 10 c0 	movl   $0xc010a426,(%esp)
c01019b3:	e8 c0 e9 ff ff       	call   c0100378 <cprintf>
c01019b8:	eb 01                	jmp    c01019bb <ide_init+0x2ca>
            continue ;
c01019ba:	90                   	nop
    for (ideno = 0; ideno < MAX_IDE; ideno ++) {
c01019bb:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c01019bf:	40                   	inc    %eax
c01019c0:	66 89 45 f6          	mov    %ax,-0xa(%ebp)
c01019c4:	0f b7 45 f6          	movzwl -0xa(%ebp),%eax
c01019c8:	83 f8 03             	cmp    $0x3,%eax
c01019cb:	0f 86 36 fd ff ff    	jbe    c0101707 <ide_init+0x16>
    }

    // enable ide interrupt
    pic_enable(IRQ_IDE1);
c01019d1:	c7 04 24 0e 00 00 00 	movl   $0xe,(%esp)
c01019d8:	e8 83 05 00 00       	call   c0101f60 <pic_enable>
    pic_enable(IRQ_IDE2);
c01019dd:	c7 04 24 0f 00 00 00 	movl   $0xf,(%esp)
c01019e4:	e8 77 05 00 00       	call   c0101f60 <pic_enable>
}
c01019e9:	90                   	nop
c01019ea:	81 c4 50 02 00 00    	add    $0x250,%esp
c01019f0:	5b                   	pop    %ebx
c01019f1:	5f                   	pop    %edi
c01019f2:	5d                   	pop    %ebp
c01019f3:	c3                   	ret    

c01019f4 <ide_device_valid>:

bool
ide_device_valid(unsigned short ideno) {
c01019f4:	55                   	push   %ebp
c01019f5:	89 e5                	mov    %esp,%ebp
c01019f7:	83 ec 04             	sub    $0x4,%esp
c01019fa:	8b 45 08             	mov    0x8(%ebp),%eax
c01019fd:	66 89 45 fc          	mov    %ax,-0x4(%ebp)
    return VALID_IDE(ideno);
c0101a01:	0f b7 45 fc          	movzwl -0x4(%ebp),%eax
c0101a05:	83 f8 03             	cmp    $0x3,%eax
c0101a08:	77 21                	ja     c0101a2b <ide_device_valid+0x37>
c0101a0a:	0f b7 55 fc          	movzwl -0x4(%ebp),%edx
c0101a0e:	89 d0                	mov    %edx,%eax
c0101a10:	c1 e0 03             	shl    $0x3,%eax
c0101a13:	29 d0                	sub    %edx,%eax
c0101a15:	c1 e0 03             	shl    $0x3,%eax
c0101a18:	05 80 b6 12 c0       	add    $0xc012b680,%eax
c0101a1d:	0f b6 00             	movzbl (%eax),%eax
c0101a20:	84 c0                	test   %al,%al
c0101a22:	74 07                	je     c0101a2b <ide_device_valid+0x37>
c0101a24:	b8 01 00 00 00       	mov    $0x1,%eax
c0101a29:	eb 05                	jmp    c0101a30 <ide_device_valid+0x3c>
c0101a2b:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0101a30:	89 ec                	mov    %ebp,%esp
c0101a32:	5d                   	pop    %ebp
c0101a33:	c3                   	ret    

c0101a34 <ide_device_size>:

size_t
ide_device_size(unsigned short ideno) {
c0101a34:	55                   	push   %ebp
c0101a35:	89 e5                	mov    %esp,%ebp
c0101a37:	83 ec 08             	sub    $0x8,%esp
c0101a3a:	8b 45 08             	mov    0x8(%ebp),%eax
c0101a3d:	66 89 45 fc          	mov    %ax,-0x4(%ebp)
    if (ide_device_valid(ideno)) {
c0101a41:	0f b7 45 fc          	movzwl -0x4(%ebp),%eax
c0101a45:	89 04 24             	mov    %eax,(%esp)
c0101a48:	e8 a7 ff ff ff       	call   c01019f4 <ide_device_valid>
c0101a4d:	85 c0                	test   %eax,%eax
c0101a4f:	74 17                	je     c0101a68 <ide_device_size+0x34>
        return ide_devices[ideno].size;
c0101a51:	0f b7 55 fc          	movzwl -0x4(%ebp),%edx
c0101a55:	89 d0                	mov    %edx,%eax
c0101a57:	c1 e0 03             	shl    $0x3,%eax
c0101a5a:	29 d0                	sub    %edx,%eax
c0101a5c:	c1 e0 03             	shl    $0x3,%eax
c0101a5f:	05 88 b6 12 c0       	add    $0xc012b688,%eax
c0101a64:	8b 00                	mov    (%eax),%eax
c0101a66:	eb 05                	jmp    c0101a6d <ide_device_size+0x39>
    }
    return 0;
c0101a68:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0101a6d:	89 ec                	mov    %ebp,%esp
c0101a6f:	5d                   	pop    %ebp
c0101a70:	c3                   	ret    

c0101a71 <ide_read_secs>:

int
ide_read_secs(unsigned short ideno, uint32_t secno, void *dst, size_t nsecs) {
c0101a71:	55                   	push   %ebp
c0101a72:	89 e5                	mov    %esp,%ebp
c0101a74:	57                   	push   %edi
c0101a75:	53                   	push   %ebx
c0101a76:	83 ec 50             	sub    $0x50,%esp
c0101a79:	8b 45 08             	mov    0x8(%ebp),%eax
c0101a7c:	66 89 45 c4          	mov    %ax,-0x3c(%ebp)
    assert(nsecs <= MAX_NSECS && VALID_IDE(ideno));
c0101a80:	81 7d 14 80 00 00 00 	cmpl   $0x80,0x14(%ebp)
c0101a87:	77 23                	ja     c0101aac <ide_read_secs+0x3b>
c0101a89:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101a8d:	83 f8 03             	cmp    $0x3,%eax
c0101a90:	77 1a                	ja     c0101aac <ide_read_secs+0x3b>
c0101a92:	0f b7 55 c4          	movzwl -0x3c(%ebp),%edx
c0101a96:	89 d0                	mov    %edx,%eax
c0101a98:	c1 e0 03             	shl    $0x3,%eax
c0101a9b:	29 d0                	sub    %edx,%eax
c0101a9d:	c1 e0 03             	shl    $0x3,%eax
c0101aa0:	05 80 b6 12 c0       	add    $0xc012b680,%eax
c0101aa5:	0f b6 00             	movzbl (%eax),%eax
c0101aa8:	84 c0                	test   %al,%al
c0101aaa:	75 24                	jne    c0101ad0 <ide_read_secs+0x5f>
c0101aac:	c7 44 24 0c 44 a4 10 	movl   $0xc010a444,0xc(%esp)
c0101ab3:	c0 
c0101ab4:	c7 44 24 08 ff a3 10 	movl   $0xc010a3ff,0x8(%esp)
c0101abb:	c0 
c0101abc:	c7 44 24 04 9f 00 00 	movl   $0x9f,0x4(%esp)
c0101ac3:	00 
c0101ac4:	c7 04 24 14 a4 10 c0 	movl   $0xc010a414,(%esp)
c0101acb:	e8 75 f1 ff ff       	call   c0100c45 <__panic>
    assert(secno < MAX_DISK_NSECS && secno + nsecs <= MAX_DISK_NSECS);
c0101ad0:	81 7d 0c ff ff ff 0f 	cmpl   $0xfffffff,0xc(%ebp)
c0101ad7:	77 0f                	ja     c0101ae8 <ide_read_secs+0x77>
c0101ad9:	8b 55 0c             	mov    0xc(%ebp),%edx
c0101adc:	8b 45 14             	mov    0x14(%ebp),%eax
c0101adf:	01 d0                	add    %edx,%eax
c0101ae1:	3d 00 00 00 10       	cmp    $0x10000000,%eax
c0101ae6:	76 24                	jbe    c0101b0c <ide_read_secs+0x9b>
c0101ae8:	c7 44 24 0c 6c a4 10 	movl   $0xc010a46c,0xc(%esp)
c0101aef:	c0 
c0101af0:	c7 44 24 08 ff a3 10 	movl   $0xc010a3ff,0x8(%esp)
c0101af7:	c0 
c0101af8:	c7 44 24 04 a0 00 00 	movl   $0xa0,0x4(%esp)
c0101aff:	00 
c0101b00:	c7 04 24 14 a4 10 c0 	movl   $0xc010a414,(%esp)
c0101b07:	e8 39 f1 ff ff       	call   c0100c45 <__panic>
    unsigned short iobase = IO_BASE(ideno), ioctrl = IO_CTRL(ideno);
c0101b0c:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101b10:	d1 e8                	shr    %eax
c0101b12:	0f b7 c0             	movzwl %ax,%eax
c0101b15:	8b 04 85 b4 a3 10 c0 	mov    -0x3fef5c4c(,%eax,4),%eax
c0101b1c:	66 89 45 f2          	mov    %ax,-0xe(%ebp)
c0101b20:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101b24:	d1 e8                	shr    %eax
c0101b26:	0f b7 c0             	movzwl %ax,%eax
c0101b29:	0f b7 04 85 b6 a3 10 	movzwl -0x3fef5c4a(,%eax,4),%eax
c0101b30:	c0 
c0101b31:	66 89 45 f0          	mov    %ax,-0x10(%ebp)

    ide_wait_ready(iobase, 0);
c0101b35:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101b39:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0101b40:	00 
c0101b41:	89 04 24             	mov    %eax,(%esp)
c0101b44:	e8 4d fb ff ff       	call   c0101696 <ide_wait_ready>

    // generate interrupt
    outb(ioctrl + ISA_CTRL, 0);
c0101b49:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0101b4c:	83 c0 02             	add    $0x2,%eax
c0101b4f:	0f b7 c0             	movzwl %ax,%eax
c0101b52:	66 89 45 d6          	mov    %ax,-0x2a(%ebp)
c0101b56:	c6 45 d5 00          	movb   $0x0,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101b5a:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c0101b5e:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c0101b62:	ee                   	out    %al,(%dx)
}
c0101b63:	90                   	nop
    outb(iobase + ISA_SECCNT, nsecs);
c0101b64:	8b 45 14             	mov    0x14(%ebp),%eax
c0101b67:	0f b6 c0             	movzbl %al,%eax
c0101b6a:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101b6e:	83 c2 02             	add    $0x2,%edx
c0101b71:	0f b7 d2             	movzwl %dx,%edx
c0101b74:	66 89 55 da          	mov    %dx,-0x26(%ebp)
c0101b78:	88 45 d9             	mov    %al,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101b7b:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c0101b7f:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c0101b83:	ee                   	out    %al,(%dx)
}
c0101b84:	90                   	nop
    outb(iobase + ISA_SECTOR, secno & 0xFF);
c0101b85:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101b88:	0f b6 c0             	movzbl %al,%eax
c0101b8b:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101b8f:	83 c2 03             	add    $0x3,%edx
c0101b92:	0f b7 d2             	movzwl %dx,%edx
c0101b95:	66 89 55 de          	mov    %dx,-0x22(%ebp)
c0101b99:	88 45 dd             	mov    %al,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101b9c:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c0101ba0:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c0101ba4:	ee                   	out    %al,(%dx)
}
c0101ba5:	90                   	nop
    outb(iobase + ISA_CYL_LO, (secno >> 8) & 0xFF);
c0101ba6:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101ba9:	c1 e8 08             	shr    $0x8,%eax
c0101bac:	0f b6 c0             	movzbl %al,%eax
c0101baf:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101bb3:	83 c2 04             	add    $0x4,%edx
c0101bb6:	0f b7 d2             	movzwl %dx,%edx
c0101bb9:	66 89 55 e2          	mov    %dx,-0x1e(%ebp)
c0101bbd:	88 45 e1             	mov    %al,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101bc0:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c0101bc4:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c0101bc8:	ee                   	out    %al,(%dx)
}
c0101bc9:	90                   	nop
    outb(iobase + ISA_CYL_HI, (secno >> 16) & 0xFF);
c0101bca:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101bcd:	c1 e8 10             	shr    $0x10,%eax
c0101bd0:	0f b6 c0             	movzbl %al,%eax
c0101bd3:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101bd7:	83 c2 05             	add    $0x5,%edx
c0101bda:	0f b7 d2             	movzwl %dx,%edx
c0101bdd:	66 89 55 e6          	mov    %dx,-0x1a(%ebp)
c0101be1:	88 45 e5             	mov    %al,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101be4:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0101be8:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0101bec:	ee                   	out    %al,(%dx)
}
c0101bed:	90                   	nop
    outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4) | ((secno >> 24) & 0xF));
c0101bee:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0101bf1:	c0 e0 04             	shl    $0x4,%al
c0101bf4:	24 10                	and    $0x10,%al
c0101bf6:	88 c2                	mov    %al,%dl
c0101bf8:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101bfb:	c1 e8 18             	shr    $0x18,%eax
c0101bfe:	24 0f                	and    $0xf,%al
c0101c00:	08 d0                	or     %dl,%al
c0101c02:	0c e0                	or     $0xe0,%al
c0101c04:	0f b6 c0             	movzbl %al,%eax
c0101c07:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101c0b:	83 c2 06             	add    $0x6,%edx
c0101c0e:	0f b7 d2             	movzwl %dx,%edx
c0101c11:	66 89 55 ea          	mov    %dx,-0x16(%ebp)
c0101c15:	88 45 e9             	mov    %al,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101c18:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0101c1c:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0101c20:	ee                   	out    %al,(%dx)
}
c0101c21:	90                   	nop
    outb(iobase + ISA_COMMAND, IDE_CMD_READ);
c0101c22:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101c26:	83 c0 07             	add    $0x7,%eax
c0101c29:	0f b7 c0             	movzwl %ax,%eax
c0101c2c:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0101c30:	c6 45 ed 20          	movb   $0x20,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101c34:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0101c38:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0101c3c:	ee                   	out    %al,(%dx)
}
c0101c3d:	90                   	nop

    int ret = 0;
c0101c3e:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    for (; nsecs > 0; nsecs --, dst += SECTSIZE) {
c0101c45:	eb 58                	jmp    c0101c9f <ide_read_secs+0x22e>
        if ((ret = ide_wait_ready(iobase, 1)) != 0) {
c0101c47:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101c4b:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0101c52:	00 
c0101c53:	89 04 24             	mov    %eax,(%esp)
c0101c56:	e8 3b fa ff ff       	call   c0101696 <ide_wait_ready>
c0101c5b:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0101c5e:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0101c62:	75 43                	jne    c0101ca7 <ide_read_secs+0x236>
            goto out;
        }
        insl(iobase, dst, SECTSIZE / sizeof(uint32_t));
c0101c64:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101c68:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0101c6b:	8b 45 10             	mov    0x10(%ebp),%eax
c0101c6e:	89 45 cc             	mov    %eax,-0x34(%ebp)
c0101c71:	c7 45 c8 80 00 00 00 	movl   $0x80,-0x38(%ebp)
    asm volatile (
c0101c78:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0101c7b:	8b 4d cc             	mov    -0x34(%ebp),%ecx
c0101c7e:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0101c81:	89 cb                	mov    %ecx,%ebx
c0101c83:	89 df                	mov    %ebx,%edi
c0101c85:	89 c1                	mov    %eax,%ecx
c0101c87:	fc                   	cld    
c0101c88:	f2 6d                	repnz insl (%dx),%es:(%edi)
c0101c8a:	89 c8                	mov    %ecx,%eax
c0101c8c:	89 fb                	mov    %edi,%ebx
c0101c8e:	89 5d cc             	mov    %ebx,-0x34(%ebp)
c0101c91:	89 45 c8             	mov    %eax,-0x38(%ebp)
}
c0101c94:	90                   	nop
    for (; nsecs > 0; nsecs --, dst += SECTSIZE) {
c0101c95:	ff 4d 14             	decl   0x14(%ebp)
c0101c98:	81 45 10 00 02 00 00 	addl   $0x200,0x10(%ebp)
c0101c9f:	83 7d 14 00          	cmpl   $0x0,0x14(%ebp)
c0101ca3:	75 a2                	jne    c0101c47 <ide_read_secs+0x1d6>
    }

out:
c0101ca5:	eb 01                	jmp    c0101ca8 <ide_read_secs+0x237>
            goto out;
c0101ca7:	90                   	nop
    return ret;
c0101ca8:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0101cab:	83 c4 50             	add    $0x50,%esp
c0101cae:	5b                   	pop    %ebx
c0101caf:	5f                   	pop    %edi
c0101cb0:	5d                   	pop    %ebp
c0101cb1:	c3                   	ret    

c0101cb2 <ide_write_secs>:

int
ide_write_secs(unsigned short ideno, uint32_t secno, const void *src, size_t nsecs) {
c0101cb2:	55                   	push   %ebp
c0101cb3:	89 e5                	mov    %esp,%ebp
c0101cb5:	56                   	push   %esi
c0101cb6:	53                   	push   %ebx
c0101cb7:	83 ec 50             	sub    $0x50,%esp
c0101cba:	8b 45 08             	mov    0x8(%ebp),%eax
c0101cbd:	66 89 45 c4          	mov    %ax,-0x3c(%ebp)
    assert(nsecs <= MAX_NSECS && VALID_IDE(ideno));
c0101cc1:	81 7d 14 80 00 00 00 	cmpl   $0x80,0x14(%ebp)
c0101cc8:	77 23                	ja     c0101ced <ide_write_secs+0x3b>
c0101cca:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101cce:	83 f8 03             	cmp    $0x3,%eax
c0101cd1:	77 1a                	ja     c0101ced <ide_write_secs+0x3b>
c0101cd3:	0f b7 55 c4          	movzwl -0x3c(%ebp),%edx
c0101cd7:	89 d0                	mov    %edx,%eax
c0101cd9:	c1 e0 03             	shl    $0x3,%eax
c0101cdc:	29 d0                	sub    %edx,%eax
c0101cde:	c1 e0 03             	shl    $0x3,%eax
c0101ce1:	05 80 b6 12 c0       	add    $0xc012b680,%eax
c0101ce6:	0f b6 00             	movzbl (%eax),%eax
c0101ce9:	84 c0                	test   %al,%al
c0101ceb:	75 24                	jne    c0101d11 <ide_write_secs+0x5f>
c0101ced:	c7 44 24 0c 44 a4 10 	movl   $0xc010a444,0xc(%esp)
c0101cf4:	c0 
c0101cf5:	c7 44 24 08 ff a3 10 	movl   $0xc010a3ff,0x8(%esp)
c0101cfc:	c0 
c0101cfd:	c7 44 24 04 bc 00 00 	movl   $0xbc,0x4(%esp)
c0101d04:	00 
c0101d05:	c7 04 24 14 a4 10 c0 	movl   $0xc010a414,(%esp)
c0101d0c:	e8 34 ef ff ff       	call   c0100c45 <__panic>
    assert(secno < MAX_DISK_NSECS && secno + nsecs <= MAX_DISK_NSECS);
c0101d11:	81 7d 0c ff ff ff 0f 	cmpl   $0xfffffff,0xc(%ebp)
c0101d18:	77 0f                	ja     c0101d29 <ide_write_secs+0x77>
c0101d1a:	8b 55 0c             	mov    0xc(%ebp),%edx
c0101d1d:	8b 45 14             	mov    0x14(%ebp),%eax
c0101d20:	01 d0                	add    %edx,%eax
c0101d22:	3d 00 00 00 10       	cmp    $0x10000000,%eax
c0101d27:	76 24                	jbe    c0101d4d <ide_write_secs+0x9b>
c0101d29:	c7 44 24 0c 6c a4 10 	movl   $0xc010a46c,0xc(%esp)
c0101d30:	c0 
c0101d31:	c7 44 24 08 ff a3 10 	movl   $0xc010a3ff,0x8(%esp)
c0101d38:	c0 
c0101d39:	c7 44 24 04 bd 00 00 	movl   $0xbd,0x4(%esp)
c0101d40:	00 
c0101d41:	c7 04 24 14 a4 10 c0 	movl   $0xc010a414,(%esp)
c0101d48:	e8 f8 ee ff ff       	call   c0100c45 <__panic>
    unsigned short iobase = IO_BASE(ideno), ioctrl = IO_CTRL(ideno);
c0101d4d:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101d51:	d1 e8                	shr    %eax
c0101d53:	0f b7 c0             	movzwl %ax,%eax
c0101d56:	8b 04 85 b4 a3 10 c0 	mov    -0x3fef5c4c(,%eax,4),%eax
c0101d5d:	66 89 45 f2          	mov    %ax,-0xe(%ebp)
c0101d61:	0f b7 45 c4          	movzwl -0x3c(%ebp),%eax
c0101d65:	d1 e8                	shr    %eax
c0101d67:	0f b7 c0             	movzwl %ax,%eax
c0101d6a:	0f b7 04 85 b6 a3 10 	movzwl -0x3fef5c4a(,%eax,4),%eax
c0101d71:	c0 
c0101d72:	66 89 45 f0          	mov    %ax,-0x10(%ebp)

    ide_wait_ready(iobase, 0);
c0101d76:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101d7a:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0101d81:	00 
c0101d82:	89 04 24             	mov    %eax,(%esp)
c0101d85:	e8 0c f9 ff ff       	call   c0101696 <ide_wait_ready>

    // generate interrupt
    outb(ioctrl + ISA_CTRL, 0);
c0101d8a:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0101d8d:	83 c0 02             	add    $0x2,%eax
c0101d90:	0f b7 c0             	movzwl %ax,%eax
c0101d93:	66 89 45 d6          	mov    %ax,-0x2a(%ebp)
c0101d97:	c6 45 d5 00          	movb   $0x0,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101d9b:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c0101d9f:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c0101da3:	ee                   	out    %al,(%dx)
}
c0101da4:	90                   	nop
    outb(iobase + ISA_SECCNT, nsecs);
c0101da5:	8b 45 14             	mov    0x14(%ebp),%eax
c0101da8:	0f b6 c0             	movzbl %al,%eax
c0101dab:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101daf:	83 c2 02             	add    $0x2,%edx
c0101db2:	0f b7 d2             	movzwl %dx,%edx
c0101db5:	66 89 55 da          	mov    %dx,-0x26(%ebp)
c0101db9:	88 45 d9             	mov    %al,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101dbc:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c0101dc0:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c0101dc4:	ee                   	out    %al,(%dx)
}
c0101dc5:	90                   	nop
    outb(iobase + ISA_SECTOR, secno & 0xFF);
c0101dc6:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101dc9:	0f b6 c0             	movzbl %al,%eax
c0101dcc:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101dd0:	83 c2 03             	add    $0x3,%edx
c0101dd3:	0f b7 d2             	movzwl %dx,%edx
c0101dd6:	66 89 55 de          	mov    %dx,-0x22(%ebp)
c0101dda:	88 45 dd             	mov    %al,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101ddd:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c0101de1:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c0101de5:	ee                   	out    %al,(%dx)
}
c0101de6:	90                   	nop
    outb(iobase + ISA_CYL_LO, (secno >> 8) & 0xFF);
c0101de7:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101dea:	c1 e8 08             	shr    $0x8,%eax
c0101ded:	0f b6 c0             	movzbl %al,%eax
c0101df0:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101df4:	83 c2 04             	add    $0x4,%edx
c0101df7:	0f b7 d2             	movzwl %dx,%edx
c0101dfa:	66 89 55 e2          	mov    %dx,-0x1e(%ebp)
c0101dfe:	88 45 e1             	mov    %al,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101e01:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c0101e05:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c0101e09:	ee                   	out    %al,(%dx)
}
c0101e0a:	90                   	nop
    outb(iobase + ISA_CYL_HI, (secno >> 16) & 0xFF);
c0101e0b:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101e0e:	c1 e8 10             	shr    $0x10,%eax
c0101e11:	0f b6 c0             	movzbl %al,%eax
c0101e14:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101e18:	83 c2 05             	add    $0x5,%edx
c0101e1b:	0f b7 d2             	movzwl %dx,%edx
c0101e1e:	66 89 55 e6          	mov    %dx,-0x1a(%ebp)
c0101e22:	88 45 e5             	mov    %al,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101e25:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c0101e29:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0101e2d:	ee                   	out    %al,(%dx)
}
c0101e2e:	90                   	nop
    outb(iobase + ISA_SDH, 0xE0 | ((ideno & 1) << 4) | ((secno >> 24) & 0xF));
c0101e2f:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0101e32:	c0 e0 04             	shl    $0x4,%al
c0101e35:	24 10                	and    $0x10,%al
c0101e37:	88 c2                	mov    %al,%dl
c0101e39:	8b 45 0c             	mov    0xc(%ebp),%eax
c0101e3c:	c1 e8 18             	shr    $0x18,%eax
c0101e3f:	24 0f                	and    $0xf,%al
c0101e41:	08 d0                	or     %dl,%al
c0101e43:	0c e0                	or     $0xe0,%al
c0101e45:	0f b6 c0             	movzbl %al,%eax
c0101e48:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c0101e4c:	83 c2 06             	add    $0x6,%edx
c0101e4f:	0f b7 d2             	movzwl %dx,%edx
c0101e52:	66 89 55 ea          	mov    %dx,-0x16(%ebp)
c0101e56:	88 45 e9             	mov    %al,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101e59:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0101e5d:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0101e61:	ee                   	out    %al,(%dx)
}
c0101e62:	90                   	nop
    outb(iobase + ISA_COMMAND, IDE_CMD_WRITE);
c0101e63:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101e67:	83 c0 07             	add    $0x7,%eax
c0101e6a:	0f b7 c0             	movzwl %ax,%eax
c0101e6d:	66 89 45 ee          	mov    %ax,-0x12(%ebp)
c0101e71:	c6 45 ed 30          	movb   $0x30,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101e75:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0101e79:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c0101e7d:	ee                   	out    %al,(%dx)
}
c0101e7e:	90                   	nop

    int ret = 0;
c0101e7f:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    for (; nsecs > 0; nsecs --, src += SECTSIZE) {
c0101e86:	eb 58                	jmp    c0101ee0 <ide_write_secs+0x22e>
        if ((ret = ide_wait_ready(iobase, 1)) != 0) {
c0101e88:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101e8c:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0101e93:	00 
c0101e94:	89 04 24             	mov    %eax,(%esp)
c0101e97:	e8 fa f7 ff ff       	call   c0101696 <ide_wait_ready>
c0101e9c:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0101e9f:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0101ea3:	75 43                	jne    c0101ee8 <ide_write_secs+0x236>
            goto out;
        }
        outsl(iobase, src, SECTSIZE / sizeof(uint32_t));
c0101ea5:	0f b7 45 f2          	movzwl -0xe(%ebp),%eax
c0101ea9:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0101eac:	8b 45 10             	mov    0x10(%ebp),%eax
c0101eaf:	89 45 cc             	mov    %eax,-0x34(%ebp)
c0101eb2:	c7 45 c8 80 00 00 00 	movl   $0x80,-0x38(%ebp)
    asm volatile (
c0101eb9:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0101ebc:	8b 4d cc             	mov    -0x34(%ebp),%ecx
c0101ebf:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0101ec2:	89 cb                	mov    %ecx,%ebx
c0101ec4:	89 de                	mov    %ebx,%esi
c0101ec6:	89 c1                	mov    %eax,%ecx
c0101ec8:	fc                   	cld    
c0101ec9:	f2 6f                	repnz outsl %ds:(%esi),(%dx)
c0101ecb:	89 c8                	mov    %ecx,%eax
c0101ecd:	89 f3                	mov    %esi,%ebx
c0101ecf:	89 5d cc             	mov    %ebx,-0x34(%ebp)
c0101ed2:	89 45 c8             	mov    %eax,-0x38(%ebp)
}
c0101ed5:	90                   	nop
    for (; nsecs > 0; nsecs --, src += SECTSIZE) {
c0101ed6:	ff 4d 14             	decl   0x14(%ebp)
c0101ed9:	81 45 10 00 02 00 00 	addl   $0x200,0x10(%ebp)
c0101ee0:	83 7d 14 00          	cmpl   $0x0,0x14(%ebp)
c0101ee4:	75 a2                	jne    c0101e88 <ide_write_secs+0x1d6>
    }

out:
c0101ee6:	eb 01                	jmp    c0101ee9 <ide_write_secs+0x237>
            goto out;
c0101ee8:	90                   	nop
    return ret;
c0101ee9:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0101eec:	83 c4 50             	add    $0x50,%esp
c0101eef:	5b                   	pop    %ebx
c0101ef0:	5e                   	pop    %esi
c0101ef1:	5d                   	pop    %ebp
c0101ef2:	c3                   	ret    

c0101ef3 <intr_enable>:
#include <x86.h>
#include <intr.h>

/* intr_enable - enable irq interrupt */
void
intr_enable(void) {
c0101ef3:	55                   	push   %ebp
c0101ef4:	89 e5                	mov    %esp,%ebp
    asm volatile ("sti");
c0101ef6:	fb                   	sti    
}
c0101ef7:	90                   	nop
    sti();
}
c0101ef8:	90                   	nop
c0101ef9:	5d                   	pop    %ebp
c0101efa:	c3                   	ret    

c0101efb <intr_disable>:

/* intr_disable - disable irq interrupt */
void
intr_disable(void) {
c0101efb:	55                   	push   %ebp
c0101efc:	89 e5                	mov    %esp,%ebp
    asm volatile ("cli" ::: "memory");
c0101efe:	fa                   	cli    
}
c0101eff:	90                   	nop
    cli();
}
c0101f00:	90                   	nop
c0101f01:	5d                   	pop    %ebp
c0101f02:	c3                   	ret    

c0101f03 <pic_setmask>:
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
static uint16_t irq_mask = 0xFFFF & ~(1 << IRQ_SLAVE);
static bool did_init = 0;

static void
pic_setmask(uint16_t mask) {
c0101f03:	55                   	push   %ebp
c0101f04:	89 e5                	mov    %esp,%ebp
c0101f06:	83 ec 14             	sub    $0x14,%esp
c0101f09:	8b 45 08             	mov    0x8(%ebp),%eax
c0101f0c:	66 89 45 ec          	mov    %ax,-0x14(%ebp)
    irq_mask = mask;
c0101f10:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101f13:	66 a3 50 85 12 c0    	mov    %ax,0xc0128550
    if (did_init) {
c0101f19:	a1 60 b7 12 c0       	mov    0xc012b760,%eax
c0101f1e:	85 c0                	test   %eax,%eax
c0101f20:	74 39                	je     c0101f5b <pic_setmask+0x58>
        outb(IO_PIC1 + 1, mask);
c0101f22:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0101f25:	0f b6 c0             	movzbl %al,%eax
c0101f28:	66 c7 45 fa 21 00    	movw   $0x21,-0x6(%ebp)
c0101f2e:	88 45 f9             	mov    %al,-0x7(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101f31:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c0101f35:	0f b7 55 fa          	movzwl -0x6(%ebp),%edx
c0101f39:	ee                   	out    %al,(%dx)
}
c0101f3a:	90                   	nop
        outb(IO_PIC2 + 1, mask >> 8);
c0101f3b:	0f b7 45 ec          	movzwl -0x14(%ebp),%eax
c0101f3f:	c1 e8 08             	shr    $0x8,%eax
c0101f42:	0f b7 c0             	movzwl %ax,%eax
c0101f45:	0f b6 c0             	movzbl %al,%eax
c0101f48:	66 c7 45 fe a1 00    	movw   $0xa1,-0x2(%ebp)
c0101f4e:	88 45 fd             	mov    %al,-0x3(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101f51:	0f b6 45 fd          	movzbl -0x3(%ebp),%eax
c0101f55:	0f b7 55 fe          	movzwl -0x2(%ebp),%edx
c0101f59:	ee                   	out    %al,(%dx)
}
c0101f5a:	90                   	nop
    }
}
c0101f5b:	90                   	nop
c0101f5c:	89 ec                	mov    %ebp,%esp
c0101f5e:	5d                   	pop    %ebp
c0101f5f:	c3                   	ret    

c0101f60 <pic_enable>:

void
pic_enable(unsigned int irq) {
c0101f60:	55                   	push   %ebp
c0101f61:	89 e5                	mov    %esp,%ebp
c0101f63:	83 ec 04             	sub    $0x4,%esp
    pic_setmask(irq_mask & ~(1 << irq));
c0101f66:	8b 45 08             	mov    0x8(%ebp),%eax
c0101f69:	ba 01 00 00 00       	mov    $0x1,%edx
c0101f6e:	88 c1                	mov    %al,%cl
c0101f70:	d3 e2                	shl    %cl,%edx
c0101f72:	89 d0                	mov    %edx,%eax
c0101f74:	98                   	cwtl   
c0101f75:	f7 d0                	not    %eax
c0101f77:	0f bf d0             	movswl %ax,%edx
c0101f7a:	0f b7 05 50 85 12 c0 	movzwl 0xc0128550,%eax
c0101f81:	98                   	cwtl   
c0101f82:	21 d0                	and    %edx,%eax
c0101f84:	98                   	cwtl   
c0101f85:	0f b7 c0             	movzwl %ax,%eax
c0101f88:	89 04 24             	mov    %eax,(%esp)
c0101f8b:	e8 73 ff ff ff       	call   c0101f03 <pic_setmask>
}
c0101f90:	90                   	nop
c0101f91:	89 ec                	mov    %ebp,%esp
c0101f93:	5d                   	pop    %ebp
c0101f94:	c3                   	ret    

c0101f95 <pic_init>:

/* pic_init - initialize the 8259A interrupt controllers */
void
pic_init(void) {
c0101f95:	55                   	push   %ebp
c0101f96:	89 e5                	mov    %esp,%ebp
c0101f98:	83 ec 44             	sub    $0x44,%esp
    did_init = 1;
c0101f9b:	c7 05 60 b7 12 c0 01 	movl   $0x1,0xc012b760
c0101fa2:	00 00 00 
c0101fa5:	66 c7 45 ca 21 00    	movw   $0x21,-0x36(%ebp)
c0101fab:	c6 45 c9 ff          	movb   $0xff,-0x37(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101faf:	0f b6 45 c9          	movzbl -0x37(%ebp),%eax
c0101fb3:	0f b7 55 ca          	movzwl -0x36(%ebp),%edx
c0101fb7:	ee                   	out    %al,(%dx)
}
c0101fb8:	90                   	nop
c0101fb9:	66 c7 45 ce a1 00    	movw   $0xa1,-0x32(%ebp)
c0101fbf:	c6 45 cd ff          	movb   $0xff,-0x33(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101fc3:	0f b6 45 cd          	movzbl -0x33(%ebp),%eax
c0101fc7:	0f b7 55 ce          	movzwl -0x32(%ebp),%edx
c0101fcb:	ee                   	out    %al,(%dx)
}
c0101fcc:	90                   	nop
c0101fcd:	66 c7 45 d2 20 00    	movw   $0x20,-0x2e(%ebp)
c0101fd3:	c6 45 d1 11          	movb   $0x11,-0x2f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101fd7:	0f b6 45 d1          	movzbl -0x2f(%ebp),%eax
c0101fdb:	0f b7 55 d2          	movzwl -0x2e(%ebp),%edx
c0101fdf:	ee                   	out    %al,(%dx)
}
c0101fe0:	90                   	nop
c0101fe1:	66 c7 45 d6 21 00    	movw   $0x21,-0x2a(%ebp)
c0101fe7:	c6 45 d5 20          	movb   $0x20,-0x2b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101feb:	0f b6 45 d5          	movzbl -0x2b(%ebp),%eax
c0101fef:	0f b7 55 d6          	movzwl -0x2a(%ebp),%edx
c0101ff3:	ee                   	out    %al,(%dx)
}
c0101ff4:	90                   	nop
c0101ff5:	66 c7 45 da 21 00    	movw   $0x21,-0x26(%ebp)
c0101ffb:	c6 45 d9 04          	movb   $0x4,-0x27(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0101fff:	0f b6 45 d9          	movzbl -0x27(%ebp),%eax
c0102003:	0f b7 55 da          	movzwl -0x26(%ebp),%edx
c0102007:	ee                   	out    %al,(%dx)
}
c0102008:	90                   	nop
c0102009:	66 c7 45 de 21 00    	movw   $0x21,-0x22(%ebp)
c010200f:	c6 45 dd 03          	movb   $0x3,-0x23(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102013:	0f b6 45 dd          	movzbl -0x23(%ebp),%eax
c0102017:	0f b7 55 de          	movzwl -0x22(%ebp),%edx
c010201b:	ee                   	out    %al,(%dx)
}
c010201c:	90                   	nop
c010201d:	66 c7 45 e2 a0 00    	movw   $0xa0,-0x1e(%ebp)
c0102023:	c6 45 e1 11          	movb   $0x11,-0x1f(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102027:	0f b6 45 e1          	movzbl -0x1f(%ebp),%eax
c010202b:	0f b7 55 e2          	movzwl -0x1e(%ebp),%edx
c010202f:	ee                   	out    %al,(%dx)
}
c0102030:	90                   	nop
c0102031:	66 c7 45 e6 a1 00    	movw   $0xa1,-0x1a(%ebp)
c0102037:	c6 45 e5 28          	movb   $0x28,-0x1b(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010203b:	0f b6 45 e5          	movzbl -0x1b(%ebp),%eax
c010203f:	0f b7 55 e6          	movzwl -0x1a(%ebp),%edx
c0102043:	ee                   	out    %al,(%dx)
}
c0102044:	90                   	nop
c0102045:	66 c7 45 ea a1 00    	movw   $0xa1,-0x16(%ebp)
c010204b:	c6 45 e9 02          	movb   $0x2,-0x17(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010204f:	0f b6 45 e9          	movzbl -0x17(%ebp),%eax
c0102053:	0f b7 55 ea          	movzwl -0x16(%ebp),%edx
c0102057:	ee                   	out    %al,(%dx)
}
c0102058:	90                   	nop
c0102059:	66 c7 45 ee a1 00    	movw   $0xa1,-0x12(%ebp)
c010205f:	c6 45 ed 03          	movb   $0x3,-0x13(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102063:	0f b6 45 ed          	movzbl -0x13(%ebp),%eax
c0102067:	0f b7 55 ee          	movzwl -0x12(%ebp),%edx
c010206b:	ee                   	out    %al,(%dx)
}
c010206c:	90                   	nop
c010206d:	66 c7 45 f2 20 00    	movw   $0x20,-0xe(%ebp)
c0102073:	c6 45 f1 68          	movb   $0x68,-0xf(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c0102077:	0f b6 45 f1          	movzbl -0xf(%ebp),%eax
c010207b:	0f b7 55 f2          	movzwl -0xe(%ebp),%edx
c010207f:	ee                   	out    %al,(%dx)
}
c0102080:	90                   	nop
c0102081:	66 c7 45 f6 20 00    	movw   $0x20,-0xa(%ebp)
c0102087:	c6 45 f5 0a          	movb   $0xa,-0xb(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010208b:	0f b6 45 f5          	movzbl -0xb(%ebp),%eax
c010208f:	0f b7 55 f6          	movzwl -0xa(%ebp),%edx
c0102093:	ee                   	out    %al,(%dx)
}
c0102094:	90                   	nop
c0102095:	66 c7 45 fa a0 00    	movw   $0xa0,-0x6(%ebp)
c010209b:	c6 45 f9 68          	movb   $0x68,-0x7(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c010209f:	0f b6 45 f9          	movzbl -0x7(%ebp),%eax
c01020a3:	0f b7 55 fa          	movzwl -0x6(%ebp),%edx
c01020a7:	ee                   	out    %al,(%dx)
}
c01020a8:	90                   	nop
c01020a9:	66 c7 45 fe a0 00    	movw   $0xa0,-0x2(%ebp)
c01020af:	c6 45 fd 0a          	movb   $0xa,-0x3(%ebp)
    asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory");
c01020b3:	0f b6 45 fd          	movzbl -0x3(%ebp),%eax
c01020b7:	0f b7 55 fe          	movzwl -0x2(%ebp),%edx
c01020bb:	ee                   	out    %al,(%dx)
}
c01020bc:	90                   	nop
    outb(IO_PIC1, 0x0a);    // read IRR by default

    outb(IO_PIC2, 0x68);    // OCW3
    outb(IO_PIC2, 0x0a);    // OCW3

    if (irq_mask != 0xFFFF) {
c01020bd:	0f b7 05 50 85 12 c0 	movzwl 0xc0128550,%eax
c01020c4:	3d ff ff 00 00       	cmp    $0xffff,%eax
c01020c9:	74 0f                	je     c01020da <pic_init+0x145>
        pic_setmask(irq_mask);
c01020cb:	0f b7 05 50 85 12 c0 	movzwl 0xc0128550,%eax
c01020d2:	89 04 24             	mov    %eax,(%esp)
c01020d5:	e8 29 fe ff ff       	call   c0101f03 <pic_setmask>
    }
}
c01020da:	90                   	nop
c01020db:	89 ec                	mov    %ebp,%esp
c01020dd:	5d                   	pop    %ebp
c01020de:	c3                   	ret    

c01020df <print_ticks>:
#include <swap.h>
#include <kdebug.h>

#define TICK_NUM 100

static void print_ticks() {
c01020df:	55                   	push   %ebp
c01020e0:	89 e5                	mov    %esp,%ebp
c01020e2:	83 ec 18             	sub    $0x18,%esp
    cprintf("%d ticks\n",TICK_NUM);
c01020e5:	c7 44 24 04 64 00 00 	movl   $0x64,0x4(%esp)
c01020ec:	00 
c01020ed:	c7 04 24 c0 a4 10 c0 	movl   $0xc010a4c0,(%esp)
c01020f4:	e8 7f e2 ff ff       	call   c0100378 <cprintf>
#ifdef DEBUG_GRADE
    cprintf("End of Test.\n");
    panic("EOT: kernel seems ok.");//panic 是一个用于处理内核崩溃的函数，它会打印出错误信息并导致系统停止运行。
#endif
}
c01020f9:	90                   	nop
c01020fa:	89 ec                	mov    %ebp,%esp
c01020fc:	5d                   	pop    %ebp
c01020fd:	c3                   	ret    

c01020fe <idt_init>:
    sizeof(idt) - 1, (uintptr_t)idt
};

/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */
void
idt_init(void) {
c01020fe:	55                   	push   %ebp
c01020ff:	89 e5                	mov    %esp,%ebp
c0102101:	83 ec 10             	sub    $0x10,%esp
      *     Notice: the argument of lidt is idt_pd. try to find it!
      */

    extern uintptr_t __vectors[];//声明了一个外部数组 __vectors，该数组存储中断服务例程（ISR）的地址。
    int i;
    for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
c0102104:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
c010210b:	e9 c4 00 00 00       	jmp    c01021d4 <idt_init+0xd6>
        SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);
c0102110:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102113:	8b 04 85 e0 85 12 c0 	mov    -0x3fed7a20(,%eax,4),%eax
c010211a:	0f b7 d0             	movzwl %ax,%edx
c010211d:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102120:	66 89 14 c5 e0 b7 12 	mov    %dx,-0x3fed4820(,%eax,8)
c0102127:	c0 
c0102128:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010212b:	66 c7 04 c5 e2 b7 12 	movw   $0x8,-0x3fed481e(,%eax,8)
c0102132:	c0 08 00 
c0102135:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102138:	0f b6 14 c5 e4 b7 12 	movzbl -0x3fed481c(,%eax,8),%edx
c010213f:	c0 
c0102140:	80 e2 e0             	and    $0xe0,%dl
c0102143:	88 14 c5 e4 b7 12 c0 	mov    %dl,-0x3fed481c(,%eax,8)
c010214a:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010214d:	0f b6 14 c5 e4 b7 12 	movzbl -0x3fed481c(,%eax,8),%edx
c0102154:	c0 
c0102155:	80 e2 1f             	and    $0x1f,%dl
c0102158:	88 14 c5 e4 b7 12 c0 	mov    %dl,-0x3fed481c(,%eax,8)
c010215f:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0102162:	0f b6 14 c5 e5 b7 12 	movzbl -0x3fed481b(,%eax,8),%edx
c0102169:	c0 
c010216a:	80 e2 f0             	and    $0xf0,%dl
c010216d:	80 ca 0e             	or     $0xe,%dl
c0102170:	88 14 c5 e5 b7 12 c0 	mov    %dl,-0x3fed481b(,%eax,8)
c0102177:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010217a:	0f b6 14 c5 e5 b7 12 	movzbl -0x3fed481b(,%eax,8),%edx
c0102181:	c0 
c0102182:	80 e2 ef             	and    $0xef,%dl
c0102185:	88 14 c5 e5 b7 12 c0 	mov    %dl,-0x3fed481b(,%eax,8)
c010218c:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010218f:	0f b6 14 c5 e5 b7 12 	movzbl -0x3fed481b(,%eax,8),%edx
c0102196:	c0 
c0102197:	80 e2 9f             	and    $0x9f,%dl
c010219a:	88 14 c5 e5 b7 12 c0 	mov    %dl,-0x3fed481b(,%eax,8)
c01021a1:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01021a4:	0f b6 14 c5 e5 b7 12 	movzbl -0x3fed481b(,%eax,8),%edx
c01021ab:	c0 
c01021ac:	80 ca 80             	or     $0x80,%dl
c01021af:	88 14 c5 e5 b7 12 c0 	mov    %dl,-0x3fed481b(,%eax,8)
c01021b6:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01021b9:	8b 04 85 e0 85 12 c0 	mov    -0x3fed7a20(,%eax,4),%eax
c01021c0:	c1 e8 10             	shr    $0x10,%eax
c01021c3:	0f b7 d0             	movzwl %ax,%edx
c01021c6:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01021c9:	66 89 14 c5 e6 b7 12 	mov    %dx,-0x3fed481a(,%eax,8)
c01021d0:	c0 
    for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
c01021d1:	ff 45 fc             	incl   -0x4(%ebp)
c01021d4:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01021d7:	3d ff 00 00 00       	cmp    $0xff,%eax
c01021dc:	0f 86 2e ff ff ff    	jbe    c0102110 <idt_init+0x12>
    //宏用于配置每个 IDT 条目.0 表示最高特权级（内核级）GD_KTEXT: 指向内核代码段的选择子，确保 ISR 在内核代码段中执行。
	//__vectors[i]: 对应中断的 ISR 地址,DPL_KERNEL: 描述符特权级，表示该中断只能由内核级代码触发。
    // set for switch from user to kernel
    //SETGATE 这行代码特别设置了 T_SWITCH_TOK（一个特定的中断向量，用于用户态到内核态的切换）的 IDT 条目。
    //DPL_USER 表示该中断可以由用户态代码触发
    SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER);
c01021e2:	a1 c4 87 12 c0       	mov    0xc01287c4,%eax
c01021e7:	0f b7 c0             	movzwl %ax,%eax
c01021ea:	66 a3 a8 bb 12 c0    	mov    %ax,0xc012bba8
c01021f0:	66 c7 05 aa bb 12 c0 	movw   $0x8,0xc012bbaa
c01021f7:	08 00 
c01021f9:	0f b6 05 ac bb 12 c0 	movzbl 0xc012bbac,%eax
c0102200:	24 e0                	and    $0xe0,%al
c0102202:	a2 ac bb 12 c0       	mov    %al,0xc012bbac
c0102207:	0f b6 05 ac bb 12 c0 	movzbl 0xc012bbac,%eax
c010220e:	24 1f                	and    $0x1f,%al
c0102210:	a2 ac bb 12 c0       	mov    %al,0xc012bbac
c0102215:	0f b6 05 ad bb 12 c0 	movzbl 0xc012bbad,%eax
c010221c:	24 f0                	and    $0xf0,%al
c010221e:	0c 0e                	or     $0xe,%al
c0102220:	a2 ad bb 12 c0       	mov    %al,0xc012bbad
c0102225:	0f b6 05 ad bb 12 c0 	movzbl 0xc012bbad,%eax
c010222c:	24 ef                	and    $0xef,%al
c010222e:	a2 ad bb 12 c0       	mov    %al,0xc012bbad
c0102233:	0f b6 05 ad bb 12 c0 	movzbl 0xc012bbad,%eax
c010223a:	0c 60                	or     $0x60,%al
c010223c:	a2 ad bb 12 c0       	mov    %al,0xc012bbad
c0102241:	0f b6 05 ad bb 12 c0 	movzbl 0xc012bbad,%eax
c0102248:	0c 80                	or     $0x80,%al
c010224a:	a2 ad bb 12 c0       	mov    %al,0xc012bbad
c010224f:	a1 c4 87 12 c0       	mov    0xc01287c4,%eax
c0102254:	c1 e8 10             	shr    $0x10,%eax
c0102257:	0f b7 c0             	movzwl %ax,%eax
c010225a:	66 a3 ae bb 12 c0    	mov    %ax,0xc012bbae
c0102260:	c7 45 f8 60 85 12 c0 	movl   $0xc0128560,-0x8(%ebp)
    asm volatile ("lidt (%0)" :: "r" (pd) : "memory");
c0102267:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010226a:	0f 01 18             	lidtl  (%eax)
}
c010226d:	90                   	nop
	// load the IDT
    //使用 lidt 指令将 IDT 描述符加载到 CPU 中
    lidt(&idt_pd);
}
c010226e:	90                   	nop
c010226f:	89 ec                	mov    %ebp,%esp
c0102271:	5d                   	pop    %ebp
c0102272:	c3                   	ret    

c0102273 <trapname>:

static const char *
trapname(int trapno) {
c0102273:	55                   	push   %ebp
c0102274:	89 e5                	mov    %esp,%ebp
        "Alignment Check",
        "Machine-Check",
        "SIMD Floating-Point Exception"
    };
    //如果 trapno 小于数组长度，则返回对应的异常名称。
    if (trapno < sizeof(excnames)/sizeof(const char * const)) {
c0102276:	8b 45 08             	mov    0x8(%ebp),%eax
c0102279:	83 f8 13             	cmp    $0x13,%eax
c010227c:	77 0c                	ja     c010228a <trapname+0x17>
        return excnames[trapno];
c010227e:	8b 45 08             	mov    0x8(%ebp),%eax
c0102281:	8b 04 85 20 a9 10 c0 	mov    -0x3fef56e0(,%eax,4),%eax
c0102288:	eb 18                	jmp    c01022a2 <trapname+0x2f>
    }
    //如果 trapno 在 IRQ_OFFSET 和 IRQ_OFFSET + 16 之间，表示它是一个硬件中断
    if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16) {
c010228a:	83 7d 08 1f          	cmpl   $0x1f,0x8(%ebp)
c010228e:	7e 0d                	jle    c010229d <trapname+0x2a>
c0102290:	83 7d 08 2f          	cmpl   $0x2f,0x8(%ebp)
c0102294:	7f 07                	jg     c010229d <trapname+0x2a>
        return "Hardware Interrupt";
c0102296:	b8 ca a4 10 c0       	mov    $0xc010a4ca,%eax
c010229b:	eb 05                	jmp    c01022a2 <trapname+0x2f>
    }
    return "(unknown trap)";
c010229d:	b8 dd a4 10 c0       	mov    $0xc010a4dd,%eax
}
c01022a2:	5d                   	pop    %ebp
c01022a3:	c3                   	ret    

c01022a4 <trap_in_kernel>:

/* trap_in_kernel - test if trap happened in kernel */
bool
trap_in_kernel(struct trapframe *tf) {
c01022a4:	55                   	push   %ebp
c01022a5:	89 e5                	mov    %esp,%ebp
    return (tf->tf_cs == (uint16_t)KERNEL_CS);
c01022a7:	8b 45 08             	mov    0x8(%ebp),%eax
c01022aa:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c01022ae:	83 f8 08             	cmp    $0x8,%eax
c01022b1:	0f 94 c0             	sete   %al
c01022b4:	0f b6 c0             	movzbl %al,%eax
    //函数通过检查 tf 中的 tf_cs 字段来判断当前处于哪个特权级,tf_cs 存储了当前代码段选择子的值
    //当 tf->tf_cs 等于 KERNEL_CS 时，表示陷阱发生在内核模式下
}
c01022b7:	5d                   	pop    %ebp
c01022b8:	c3                   	ret    

c01022b9 <print_trapframe>:
    "TF", "IF", "DF", "OF", NULL, NULL, "NT", NULL,
    "RF", "VM", "AC", "VIF", "VIP", "ID", NULL, NULL,
};
//struct trapframe *tf，一个指向 trapframe 结构的指针，包含有关陷阱发生时的 CPU 状态的信息。
void
print_trapframe(struct trapframe *tf) {
c01022b9:	55                   	push   %ebp
c01022ba:	89 e5                	mov    %esp,%ebp
c01022bc:	83 ec 28             	sub    $0x28,%esp
    cprintf("trapframe at %p\n", tf); //打印陷阱框架地址
c01022bf:	8b 45 08             	mov    0x8(%ebp),%eax
c01022c2:	89 44 24 04          	mov    %eax,0x4(%esp)
c01022c6:	c7 04 24 1e a5 10 c0 	movl   $0xc010a51e,(%esp)
c01022cd:	e8 a6 e0 ff ff       	call   c0100378 <cprintf>
    print_regs(&tf->tf_regs); //打印寄存器状态
c01022d2:	8b 45 08             	mov    0x8(%ebp),%eax
c01022d5:	89 04 24             	mov    %eax,(%esp)
c01022d8:	e8 8f 01 00 00       	call   c010246c <print_regs>
    //打印数据段（DS）、扩展段（ES）、文件段（FS）、通用段（GS）的值。
    cprintf("  ds   0x----%04x\n", tf->tf_ds);
c01022dd:	8b 45 08             	mov    0x8(%ebp),%eax
c01022e0:	0f b7 40 2c          	movzwl 0x2c(%eax),%eax
c01022e4:	89 44 24 04          	mov    %eax,0x4(%esp)
c01022e8:	c7 04 24 2f a5 10 c0 	movl   $0xc010a52f,(%esp)
c01022ef:	e8 84 e0 ff ff       	call   c0100378 <cprintf>
    cprintf("  es   0x----%04x\n", tf->tf_es);
c01022f4:	8b 45 08             	mov    0x8(%ebp),%eax
c01022f7:	0f b7 40 28          	movzwl 0x28(%eax),%eax
c01022fb:	89 44 24 04          	mov    %eax,0x4(%esp)
c01022ff:	c7 04 24 42 a5 10 c0 	movl   $0xc010a542,(%esp)
c0102306:	e8 6d e0 ff ff       	call   c0100378 <cprintf>
    cprintf("  fs   0x----%04x\n", tf->tf_fs);
c010230b:	8b 45 08             	mov    0x8(%ebp),%eax
c010230e:	0f b7 40 24          	movzwl 0x24(%eax),%eax
c0102312:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102316:	c7 04 24 55 a5 10 c0 	movl   $0xc010a555,(%esp)
c010231d:	e8 56 e0 ff ff       	call   c0100378 <cprintf>
    cprintf("  gs   0x----%04x\n", tf->tf_gs);
c0102322:	8b 45 08             	mov    0x8(%ebp),%eax
c0102325:	0f b7 40 20          	movzwl 0x20(%eax),%eax
c0102329:	89 44 24 04          	mov    %eax,0x4(%esp)
c010232d:	c7 04 24 68 a5 10 c0 	movl   $0xc010a568,(%esp)
c0102334:	e8 3f e0 ff ff       	call   c0100378 <cprintf>
    // 打印陷阱号（trap number）及其对应的名称，通过调用 trapname 函数获取。
    cprintf("  trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno));
c0102339:	8b 45 08             	mov    0x8(%ebp),%eax
c010233c:	8b 40 30             	mov    0x30(%eax),%eax
c010233f:	89 04 24             	mov    %eax,(%esp)
c0102342:	e8 2c ff ff ff       	call   c0102273 <trapname>
c0102347:	8b 55 08             	mov    0x8(%ebp),%edx
c010234a:	8b 52 30             	mov    0x30(%edx),%edx
c010234d:	89 44 24 08          	mov    %eax,0x8(%esp)
c0102351:	89 54 24 04          	mov    %edx,0x4(%esp)
c0102355:	c7 04 24 7b a5 10 c0 	movl   $0xc010a57b,(%esp)
c010235c:	e8 17 e0 ff ff       	call   c0100378 <cprintf>
    cprintf("  err  0x%08x\n", tf->tf_err);// 如果有错误代码，打印该字段的值。
c0102361:	8b 45 08             	mov    0x8(%ebp),%eax
c0102364:	8b 40 34             	mov    0x34(%eax),%eax
c0102367:	89 44 24 04          	mov    %eax,0x4(%esp)
c010236b:	c7 04 24 8d a5 10 c0 	movl   $0xc010a58d,(%esp)
c0102372:	e8 01 e0 ff ff       	call   c0100378 <cprintf>
    cprintf("  eip  0x%08x\n", tf->tf_eip);//打印当前执行的指令指针（EIP），指向出错或中断的指令。
c0102377:	8b 45 08             	mov    0x8(%ebp),%eax
c010237a:	8b 40 38             	mov    0x38(%eax),%eax
c010237d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102381:	c7 04 24 9c a5 10 c0 	movl   $0xc010a59c,(%esp)
c0102388:	e8 eb df ff ff       	call   c0100378 <cprintf>
    cprintf("  cs   0x----%04x\n", tf->tf_cs);//打印代码段寄存器（CS）的值。
c010238d:	8b 45 08             	mov    0x8(%ebp),%eax
c0102390:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c0102394:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102398:	c7 04 24 ab a5 10 c0 	movl   $0xc010a5ab,(%esp)
c010239f:	e8 d4 df ff ff       	call   c0100378 <cprintf>
    cprintf("  flag 0x%08x ", tf->tf_eflags);// 打印标志寄存器（EFLAGS）的值
c01023a4:	8b 45 08             	mov    0x8(%ebp),%eax
c01023a7:	8b 40 40             	mov    0x40(%eax),%eax
c01023aa:	89 44 24 04          	mov    %eax,0x4(%esp)
c01023ae:	c7 04 24 be a5 10 c0 	movl   $0xc010a5be,(%esp)
c01023b5:	e8 be df ff ff       	call   c0100378 <cprintf>
    //使用循环遍历 IA32flags 数组，j 表示当前标志位的位掩码。
    int i, j;
    for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) {
c01023ba:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c01023c1:	c7 45 f0 01 00 00 00 	movl   $0x1,-0x10(%ebp)
c01023c8:	eb 3d                	jmp    c0102407 <print_trapframe+0x14e>
        if ((tf->tf_eflags & j) && IA32flags[i] != NULL) {
c01023ca:	8b 45 08             	mov    0x8(%ebp),%eax
c01023cd:	8b 50 40             	mov    0x40(%eax),%edx
c01023d0:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01023d3:	21 d0                	and    %edx,%eax
c01023d5:	85 c0                	test   %eax,%eax
c01023d7:	74 28                	je     c0102401 <print_trapframe+0x148>
c01023d9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01023dc:	8b 04 85 80 85 12 c0 	mov    -0x3fed7a80(,%eax,4),%eax
c01023e3:	85 c0                	test   %eax,%eax
c01023e5:	74 1a                	je     c0102401 <print_trapframe+0x148>
            cprintf("%s,", IA32flags[i]);
c01023e7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01023ea:	8b 04 85 80 85 12 c0 	mov    -0x3fed7a80(,%eax,4),%eax
c01023f1:	89 44 24 04          	mov    %eax,0x4(%esp)
c01023f5:	c7 04 24 cd a5 10 c0 	movl   $0xc010a5cd,(%esp)
c01023fc:	e8 77 df ff ff       	call   c0100378 <cprintf>
    for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) {
c0102401:	ff 45 f4             	incl   -0xc(%ebp)
c0102404:	d1 65 f0             	shll   -0x10(%ebp)
c0102407:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010240a:	83 f8 17             	cmp    $0x17,%eax
c010240d:	76 bb                	jbe    c01023ca <print_trapframe+0x111>
        }
    }
    //通过位掩码 FL_IOPL_MASK 获取和打印当前的 I/O 特权级别。
    cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12);
c010240f:	8b 45 08             	mov    0x8(%ebp),%eax
c0102412:	8b 40 40             	mov    0x40(%eax),%eax
c0102415:	c1 e8 0c             	shr    $0xc,%eax
c0102418:	83 e0 03             	and    $0x3,%eax
c010241b:	89 44 24 04          	mov    %eax,0x4(%esp)
c010241f:	c7 04 24 d1 a5 10 c0 	movl   $0xc010a5d1,(%esp)
c0102426:	e8 4d df ff ff       	call   c0100378 <cprintf>
    //如果陷阱不是在内核中发生的（通过 trap_in_kernel 判断），
    //则打印栈指针（ESP）和栈段（SS）寄存器的值。
    if (!trap_in_kernel(tf)) {
c010242b:	8b 45 08             	mov    0x8(%ebp),%eax
c010242e:	89 04 24             	mov    %eax,(%esp)
c0102431:	e8 6e fe ff ff       	call   c01022a4 <trap_in_kernel>
c0102436:	85 c0                	test   %eax,%eax
c0102438:	75 2d                	jne    c0102467 <print_trapframe+0x1ae>
        cprintf("  esp  0x%08x\n", tf->tf_esp);
c010243a:	8b 45 08             	mov    0x8(%ebp),%eax
c010243d:	8b 40 44             	mov    0x44(%eax),%eax
c0102440:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102444:	c7 04 24 da a5 10 c0 	movl   $0xc010a5da,(%esp)
c010244b:	e8 28 df ff ff       	call   c0100378 <cprintf>
        cprintf("  ss   0x----%04x\n", tf->tf_ss);
c0102450:	8b 45 08             	mov    0x8(%ebp),%eax
c0102453:	0f b7 40 48          	movzwl 0x48(%eax),%eax
c0102457:	89 44 24 04          	mov    %eax,0x4(%esp)
c010245b:	c7 04 24 e9 a5 10 c0 	movl   $0xc010a5e9,(%esp)
c0102462:	e8 11 df ff ff       	call   c0100378 <cprintf>
    }
}
c0102467:	90                   	nop
c0102468:	89 ec                	mov    %ebp,%esp
c010246a:	5d                   	pop    %ebp
c010246b:	c3                   	ret    

c010246c <print_regs>:
//定义了一个名为 print_regs 的函数，
//打印出存储在 struct pushregs 结构体中的寄存器值。
void
print_regs(struct pushregs *regs) {
c010246c:	55                   	push   %ebp
c010246d:	89 e5                	mov    %esp,%ebp
c010246f:	83 ec 18             	sub    $0x18,%esp
    cprintf("  edi  0x%08x\n", regs->reg_edi);
c0102472:	8b 45 08             	mov    0x8(%ebp),%eax
c0102475:	8b 00                	mov    (%eax),%eax
c0102477:	89 44 24 04          	mov    %eax,0x4(%esp)
c010247b:	c7 04 24 fc a5 10 c0 	movl   $0xc010a5fc,(%esp)
c0102482:	e8 f1 de ff ff       	call   c0100378 <cprintf>
    cprintf("  esi  0x%08x\n", regs->reg_esi);
c0102487:	8b 45 08             	mov    0x8(%ebp),%eax
c010248a:	8b 40 04             	mov    0x4(%eax),%eax
c010248d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102491:	c7 04 24 0b a6 10 c0 	movl   $0xc010a60b,(%esp)
c0102498:	e8 db de ff ff       	call   c0100378 <cprintf>
    cprintf("  ebp  0x%08x\n", regs->reg_ebp);
c010249d:	8b 45 08             	mov    0x8(%ebp),%eax
c01024a0:	8b 40 08             	mov    0x8(%eax),%eax
c01024a3:	89 44 24 04          	mov    %eax,0x4(%esp)
c01024a7:	c7 04 24 1a a6 10 c0 	movl   $0xc010a61a,(%esp)
c01024ae:	e8 c5 de ff ff       	call   c0100378 <cprintf>
    cprintf("  oesp 0x%08x\n", regs->reg_oesp);//打印旧的栈指针（OESP），这个寄存器通常在陷阱或中断发生时用于记录上一个栈指针。
c01024b3:	8b 45 08             	mov    0x8(%ebp),%eax
c01024b6:	8b 40 0c             	mov    0xc(%eax),%eax
c01024b9:	89 44 24 04          	mov    %eax,0x4(%esp)
c01024bd:	c7 04 24 29 a6 10 c0 	movl   $0xc010a629,(%esp)
c01024c4:	e8 af de ff ff       	call   c0100378 <cprintf>
    cprintf("  ebx  0x%08x\n", regs->reg_ebx);
c01024c9:	8b 45 08             	mov    0x8(%ebp),%eax
c01024cc:	8b 40 10             	mov    0x10(%eax),%eax
c01024cf:	89 44 24 04          	mov    %eax,0x4(%esp)
c01024d3:	c7 04 24 38 a6 10 c0 	movl   $0xc010a638,(%esp)
c01024da:	e8 99 de ff ff       	call   c0100378 <cprintf>
    cprintf("  edx  0x%08x\n", regs->reg_edx);
c01024df:	8b 45 08             	mov    0x8(%ebp),%eax
c01024e2:	8b 40 14             	mov    0x14(%eax),%eax
c01024e5:	89 44 24 04          	mov    %eax,0x4(%esp)
c01024e9:	c7 04 24 47 a6 10 c0 	movl   $0xc010a647,(%esp)
c01024f0:	e8 83 de ff ff       	call   c0100378 <cprintf>
    cprintf("  ecx  0x%08x\n", regs->reg_ecx);
c01024f5:	8b 45 08             	mov    0x8(%ebp),%eax
c01024f8:	8b 40 18             	mov    0x18(%eax),%eax
c01024fb:	89 44 24 04          	mov    %eax,0x4(%esp)
c01024ff:	c7 04 24 56 a6 10 c0 	movl   $0xc010a656,(%esp)
c0102506:	e8 6d de ff ff       	call   c0100378 <cprintf>
    cprintf("  eax  0x%08x\n", regs->reg_eax);
c010250b:	8b 45 08             	mov    0x8(%ebp),%eax
c010250e:	8b 40 1c             	mov    0x1c(%eax),%eax
c0102511:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102515:	c7 04 24 65 a6 10 c0 	movl   $0xc010a665,(%esp)
c010251c:	e8 57 de ff ff       	call   c0100378 <cprintf>
}
c0102521:	90                   	nop
c0102522:	89 ec                	mov    %ebp,%esp
c0102524:	5d                   	pop    %ebp
c0102525:	c3                   	ret    

c0102526 <print_pgfault>:
 * 此函数用于输出页面故障的详细信息，包括故障地址、访问类型（读/写）、访问模式（用户/内核）以及故障类型（未找到页面/保护故障）。
 *
 * @param tf 指向 trapframe 结构的指针，包含故障发生时的寄存器状态和错误代码。
 */
static inline void
print_pgfault(struct trapframe *tf) {
c0102526:	55                   	push   %ebp
c0102527:	89 e5                	mov    %esp,%ebp
c0102529:	83 ec 38             	sub    $0x38,%esp
c010252c:	89 5d fc             	mov    %ebx,-0x4(%ebp)
     * bit 2 == 0 表示内核模式，1 表示用户模式
     * */
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
            (tf->tf_err & 4) ? 'U' : 'K',
            (tf->tf_err & 2) ? 'W' : 'R',
            (tf->tf_err & 1) ? "protection fault" : "no page found");
c010252f:	8b 45 08             	mov    0x8(%ebp),%eax
c0102532:	8b 40 34             	mov    0x34(%eax),%eax
c0102535:	83 e0 01             	and    $0x1,%eax
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
c0102538:	85 c0                	test   %eax,%eax
c010253a:	74 07                	je     c0102543 <print_pgfault+0x1d>
c010253c:	bb 74 a6 10 c0       	mov    $0xc010a674,%ebx
c0102541:	eb 05                	jmp    c0102548 <print_pgfault+0x22>
c0102543:	bb 85 a6 10 c0       	mov    $0xc010a685,%ebx
            (tf->tf_err & 2) ? 'W' : 'R',
c0102548:	8b 45 08             	mov    0x8(%ebp),%eax
c010254b:	8b 40 34             	mov    0x34(%eax),%eax
c010254e:	83 e0 02             	and    $0x2,%eax
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
c0102551:	85 c0                	test   %eax,%eax
c0102553:	74 07                	je     c010255c <print_pgfault+0x36>
c0102555:	b9 57 00 00 00       	mov    $0x57,%ecx
c010255a:	eb 05                	jmp    c0102561 <print_pgfault+0x3b>
c010255c:	b9 52 00 00 00       	mov    $0x52,%ecx
            (tf->tf_err & 4) ? 'U' : 'K',
c0102561:	8b 45 08             	mov    0x8(%ebp),%eax
c0102564:	8b 40 34             	mov    0x34(%eax),%eax
c0102567:	83 e0 04             	and    $0x4,%eax
    cprintf("page fault at 0x%08x: %c/%c [%s].\n", rcr2(),
c010256a:	85 c0                	test   %eax,%eax
c010256c:	74 07                	je     c0102575 <print_pgfault+0x4f>
c010256e:	ba 55 00 00 00       	mov    $0x55,%edx
c0102573:	eb 05                	jmp    c010257a <print_pgfault+0x54>
c0102575:	ba 4b 00 00 00       	mov    $0x4b,%edx
}

static inline uintptr_t
rcr2(void) {
    uintptr_t cr2;
    asm volatile ("mov %%cr2, %0" : "=r" (cr2) :: "memory");
c010257a:	0f 20 d0             	mov    %cr2,%eax
c010257d:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return cr2;
c0102580:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0102583:	89 5c 24 10          	mov    %ebx,0x10(%esp)
c0102587:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c010258b:	89 54 24 08          	mov    %edx,0x8(%esp)
c010258f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102593:	c7 04 24 94 a6 10 c0 	movl   $0xc010a694,(%esp)
c010259a:	e8 d9 dd ff ff       	call   c0100378 <cprintf>
}
c010259f:	90                   	nop
c01025a0:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c01025a3:	89 ec                	mov    %ebp,%esp
c01025a5:	5d                   	pop    %ebp
c01025a6:	c3                   	ret    

c01025a7 <pgfault_handler>:
 * 
 * @param tf 指向陷阱帧的指针，包含故障发生时的CPU状态信息
 * @return 返回页面故障处理的结果，或者在无法处理时引发系统崩溃
 */
static int
pgfault_handler(struct trapframe *tf) {
c01025a7:	55                   	push   %ebp
c01025a8:	89 e5                	mov    %esp,%ebp
c01025aa:	83 ec 28             	sub    $0x28,%esp
    // 声明一个外部变量，用于检查内存管理结构
    extern struct mm_struct *check_mm_struct;
    // 打印页面故障信息
    print_pgfault(tf);
c01025ad:	8b 45 08             	mov    0x8(%ebp),%eax
c01025b0:	89 04 24             	mov    %eax,(%esp)
c01025b3:	e8 6e ff ff ff       	call   c0102526 <print_pgfault>
    // 检查是否存在有效的内存管理结构
    if (check_mm_struct != NULL) {
c01025b8:	a1 6c c1 12 c0       	mov    0xc012c16c,%eax
c01025bd:	85 c0                	test   %eax,%eax
c01025bf:	74 26                	je     c01025e7 <pgfault_handler+0x40>
    asm volatile ("mov %%cr2, %0" : "=r" (cr2) :: "memory");
c01025c1:	0f 20 d0             	mov    %cr2,%eax
c01025c4:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return cr2;
c01025c7:	8b 4d f4             	mov    -0xc(%ebp),%ecx
        // 如果存在，调用页面故障处理函数
        return do_pgfault(check_mm_struct, tf->tf_err, rcr2());
c01025ca:	8b 45 08             	mov    0x8(%ebp),%eax
c01025cd:	8b 50 34             	mov    0x34(%eax),%edx
c01025d0:	a1 6c c1 12 c0       	mov    0xc012c16c,%eax
c01025d5:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c01025d9:	89 54 24 04          	mov    %edx,0x4(%esp)
c01025dd:	89 04 24             	mov    %eax,(%esp)
c01025e0:	e8 23 5e 00 00       	call   c0108408 <do_pgfault>
c01025e5:	eb 1c                	jmp    c0102603 <pgfault_handler+0x5c>
    }
    // 如果没有有效的内存管理结构，引发系统崩溃
    panic("unhandled page fault.\n");
c01025e7:	c7 44 24 08 b7 a6 10 	movl   $0xc010a6b7,0x8(%esp)
c01025ee:	c0 
c01025ef:	c7 44 24 04 d3 00 00 	movl   $0xd3,0x4(%esp)
c01025f6:	00 
c01025f7:	c7 04 24 ce a6 10 c0 	movl   $0xc010a6ce,(%esp)
c01025fe:	e8 42 e6 ff ff       	call   c0100c45 <__panic>
}
c0102603:	89 ec                	mov    %ebp,%esp
c0102605:	5d                   	pop    %ebp
c0102606:	c3                   	ret    

c0102607 <trap_dispatch>:

struct trapframe switchk2u, *switchu2k;
//定义了一个名为 trap_dispatch 的静态函数，根据发生的陷阱类型进行相应的处理。
// 参数 tf 是指向陷阱帧的指针，包含了关于陷阱发生时的CPU状态信息。
static void
trap_dispatch(struct trapframe *tf) {
c0102607:	55                   	push   %ebp
c0102608:	89 e5                	mov    %esp,%ebp
c010260a:	83 ec 28             	sub    $0x28,%esp
c010260d:	89 5d fc             	mov    %ebx,-0x4(%ebp)
    char c;

    int ret;
    //通过 switch 语句根据 tf->tf_trapno 的值来分发不同的陷阱处理逻辑。
    switch (tf->tf_trapno) {
c0102610:	8b 45 08             	mov    0x8(%ebp),%eax
c0102613:	8b 40 30             	mov    0x30(%eax),%eax
c0102616:	83 f8 79             	cmp    $0x79,%eax
c0102619:	0f 84 a2 01 00 00    	je     c01027c1 <trap_dispatch+0x1ba>
c010261f:	83 f8 79             	cmp    $0x79,%eax
c0102622:	0f 87 16 02 00 00    	ja     c010283e <trap_dispatch+0x237>
c0102628:	83 f8 2f             	cmp    $0x2f,%eax
c010262b:	77 1e                	ja     c010264b <trap_dispatch+0x44>
c010262d:	83 f8 0e             	cmp    $0xe,%eax
c0102630:	0f 82 08 02 00 00    	jb     c010283e <trap_dispatch+0x237>
c0102636:	83 e8 0e             	sub    $0xe,%eax
c0102639:	83 f8 21             	cmp    $0x21,%eax
c010263c:	0f 87 fc 01 00 00    	ja     c010283e <trap_dispatch+0x237>
c0102642:	8b 04 85 38 a7 10 c0 	mov    -0x3fef58c8(,%eax,4),%eax
c0102649:	ff e0                	jmp    *%eax
c010264b:	83 f8 78             	cmp    $0x78,%eax
c010264e:	0f 84 e3 00 00 00    	je     c0102737 <trap_dispatch+0x130>
c0102654:	e9 e5 01 00 00       	jmp    c010283e <trap_dispatch+0x237>
    case T_PGFLT:  //page fault
    // 处理页故障中断
        if ((ret = pgfault_handler(tf)) != 0) {
c0102659:	8b 45 08             	mov    0x8(%ebp),%eax
c010265c:	89 04 24             	mov    %eax,(%esp)
c010265f:	e8 43 ff ff ff       	call   c01025a7 <pgfault_handler>
c0102664:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0102667:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010266b:	0f 84 05 02 00 00    	je     c0102876 <trap_dispatch+0x26f>
            print_trapframe(tf);
c0102671:	8b 45 08             	mov    0x8(%ebp),%eax
c0102674:	89 04 24             	mov    %eax,(%esp)
c0102677:	e8 3d fc ff ff       	call   c01022b9 <print_trapframe>
            panic("handle pgfault failed. %e\n", ret);
c010267c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010267f:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0102683:	c7 44 24 08 df a6 10 	movl   $0xc010a6df,0x8(%esp)
c010268a:	c0 
c010268b:	c7 44 24 04 e7 00 00 	movl   $0xe7,0x4(%esp)
c0102692:	00 
c0102693:	c7 04 24 ce a6 10 c0 	movl   $0xc010a6ce,(%esp)
c010269a:	e8 a6 e5 ff ff       	call   c0100c45 <__panic>
        /* handle the timer interrupt */
        /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c
         * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().
         * (3) Too Simple? Yes, I think so!
         */
        ticks ++; //记录中断事件
c010269f:	a1 24 b4 12 c0       	mov    0xc012b424,%eax
c01026a4:	40                   	inc    %eax
c01026a5:	a3 24 b4 12 c0       	mov    %eax,0xc012b424
        if (ticks % TICK_NUM == 0)
c01026aa:	8b 0d 24 b4 12 c0    	mov    0xc012b424,%ecx
c01026b0:	ba 1f 85 eb 51       	mov    $0x51eb851f,%edx
c01026b5:	89 c8                	mov    %ecx,%eax
c01026b7:	f7 e2                	mul    %edx
c01026b9:	c1 ea 05             	shr    $0x5,%edx
c01026bc:	89 d0                	mov    %edx,%eax
c01026be:	c1 e0 02             	shl    $0x2,%eax
c01026c1:	01 d0                	add    %edx,%eax
c01026c3:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c01026ca:	01 d0                	add    %edx,%eax
c01026cc:	c1 e0 02             	shl    $0x2,%eax
c01026cf:	29 c1                	sub    %eax,%ecx
c01026d1:	89 ca                	mov    %ecx,%edx
c01026d3:	85 d2                	test   %edx,%edx
c01026d5:	0f 85 9e 01 00 00    	jne    c0102879 <trap_dispatch+0x272>
        {
            print_ticks();
c01026db:	e8 ff f9 ff ff       	call   c01020df <print_ticks>
        }//每经过 TICK_NUM 次周期时，调用 print_ticks() 打印信息。
        break;
c01026e0:	e9 94 01 00 00       	jmp    c0102879 <trap_dispatch+0x272>
    //处理串口中断，调用 cons_getc() 从串口读取字符并打印。
    case IRQ_OFFSET + IRQ_COM1:
        c = cons_getc();
c01026e5:	e8 3b ef ff ff       	call   c0101625 <cons_getc>
c01026ea:	88 45 f7             	mov    %al,-0x9(%ebp)
        cprintf("serial [%03d] %c\n", c, c);
c01026ed:	0f be 55 f7          	movsbl -0x9(%ebp),%edx
c01026f1:	0f be 45 f7          	movsbl -0x9(%ebp),%eax
c01026f5:	89 54 24 08          	mov    %edx,0x8(%esp)
c01026f9:	89 44 24 04          	mov    %eax,0x4(%esp)
c01026fd:	c7 04 24 fa a6 10 c0 	movl   $0xc010a6fa,(%esp)
c0102704:	e8 6f dc ff ff       	call   c0100378 <cprintf>
        break;
c0102709:	e9 72 01 00 00       	jmp    c0102880 <trap_dispatch+0x279>
    //处理键盘中断，调用 cons_getc() 读取键盘输入并打印。
    case IRQ_OFFSET + IRQ_KBD:
        c = cons_getc();
c010270e:	e8 12 ef ff ff       	call   c0101625 <cons_getc>
c0102713:	88 45 f7             	mov    %al,-0x9(%ebp)
        cprintf("kbd [%03d] %c\n", c, c);
c0102716:	0f be 55 f7          	movsbl -0x9(%ebp),%edx
c010271a:	0f be 45 f7          	movsbl -0x9(%ebp),%eax
c010271e:	89 54 24 08          	mov    %edx,0x8(%esp)
c0102722:	89 44 24 04          	mov    %eax,0x4(%esp)
c0102726:	c7 04 24 0c a7 10 c0 	movl   $0xc010a70c,(%esp)
c010272d:	e8 46 dc ff ff       	call   c0100378 <cprintf>
        break;
c0102732:	e9 49 01 00 00       	jmp    c0102880 <trap_dispatch+0x279>
    //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
    case T_SWITCH_TOU://表示发生了从内核模式切换到用户模式的请求。
        if (tf->tf_cs != USER_CS) {//判断当前是否在内核模式下
c0102737:	8b 45 08             	mov    0x8(%ebp),%eax
c010273a:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c010273e:	83 f8 1b             	cmp    $0x1b,%eax
c0102741:	0f 84 35 01 00 00    	je     c010287c <trap_dispatch+0x275>
            switchk2u = *tf; //保存当前陷阱框架
c0102747:	8b 4d 08             	mov    0x8(%ebp),%ecx
c010274a:	b8 4c 00 00 00       	mov    $0x4c,%eax
c010274f:	83 e0 fc             	and    $0xfffffffc,%eax
c0102752:	89 c3                	mov    %eax,%ebx
c0102754:	b8 00 00 00 00       	mov    $0x0,%eax
c0102759:	8b 14 01             	mov    (%ecx,%eax,1),%edx
c010275c:	89 90 80 b7 12 c0    	mov    %edx,-0x3fed4880(%eax)
c0102762:	83 c0 04             	add    $0x4,%eax
c0102765:	39 d8                	cmp    %ebx,%eax
c0102767:	72 f0                	jb     c0102759 <trap_dispatch+0x152>
            switchk2u.tf_cs = USER_CS;//设置用户模式的段寄存器
c0102769:	66 c7 05 bc b7 12 c0 	movw   $0x1b,0xc012b7bc
c0102770:	1b 00 
            //将数据段和栈段寄存器 都设置为 USER_DS（用户数据段）
            switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS;
c0102772:	66 c7 05 c8 b7 12 c0 	movw   $0x23,0xc012b7c8
c0102779:	23 00 
c010277b:	0f b7 05 c8 b7 12 c0 	movzwl 0xc012b7c8,%eax
c0102782:	66 a3 a8 b7 12 c0    	mov    %ax,0xc012b7a8
c0102788:	0f b7 05 a8 b7 12 c0 	movzwl 0xc012b7a8,%eax
c010278f:	66 a3 ac b7 12 c0    	mov    %ax,0xc012b7ac
            switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8;
c0102795:	8b 45 08             	mov    0x8(%ebp),%eax
c0102798:	83 c0 44             	add    $0x44,%eax
c010279b:	a3 c4 b7 12 c0       	mov    %eax,0xc012b7c4
        
            // set eflags, make sure ucore can use io under user mode.
            // if CPL > IOPL, then cpu will generate a general protection.
            switchk2u.tf_eflags |= FL_IOPL_MASK;//允许用户模式下进行 I/O 操作
c01027a0:	a1 c0 b7 12 c0       	mov    0xc012b7c0,%eax
c01027a5:	0d 00 30 00 00       	or     $0x3000,%eax
c01027aa:	a3 c0 b7 12 c0       	mov    %eax,0xc012b7c0
        
            // set temporary stack
            // then iret will jump to the right stack
            *((uint32_t *)tf - 1) = (uint32_t)&switchk2u;
c01027af:	8b 45 08             	mov    0x8(%ebp),%eax
c01027b2:	83 e8 04             	sub    $0x4,%eax
c01027b5:	ba 80 b7 12 c0       	mov    $0xc012b780,%edx
c01027ba:	89 10                	mov    %edx,(%eax)
        }
        break;
c01027bc:	e9 bb 00 00 00       	jmp    c010287c <trap_dispatch+0x275>
    case T_SWITCH_TOK://T_SWITCH_TOK 表示发生了从用户模式切换到内核模式的请求。
        if (tf->tf_cs != KERNEL_CS) { //判断当前是否在用户模式下
c01027c1:	8b 45 08             	mov    0x8(%ebp),%eax
c01027c4:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c01027c8:	83 f8 08             	cmp    $0x8,%eax
c01027cb:	0f 84 ae 00 00 00    	je     c010287f <trap_dispatch+0x278>
            tf->tf_cs = KERNEL_CS;
c01027d1:	8b 45 08             	mov    0x8(%ebp),%eax
c01027d4:	66 c7 40 3c 08 00    	movw   $0x8,0x3c(%eax)
            tf->tf_ds = tf->tf_es = KERNEL_DS;
c01027da:	8b 45 08             	mov    0x8(%ebp),%eax
c01027dd:	66 c7 40 28 10 00    	movw   $0x10,0x28(%eax)
c01027e3:	8b 45 08             	mov    0x8(%ebp),%eax
c01027e6:	0f b7 50 28          	movzwl 0x28(%eax),%edx
c01027ea:	8b 45 08             	mov    0x8(%ebp),%eax
c01027ed:	66 89 50 2c          	mov    %dx,0x2c(%eax)
            //设置内核模式的段寄存器
            tf->tf_eflags &= ~FL_IOPL_MASK; //清除 I/O 权限标志
c01027f1:	8b 45 08             	mov    0x8(%ebp),%eax
c01027f4:	8b 40 40             	mov    0x40(%eax),%eax
c01027f7:	25 ff cf ff ff       	and    $0xffffcfff,%eax
c01027fc:	89 c2                	mov    %eax,%edx
c01027fe:	8b 45 08             	mov    0x8(%ebp),%eax
c0102801:	89 50 40             	mov    %edx,0x40(%eax)
            switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8));
c0102804:	8b 45 08             	mov    0x8(%ebp),%eax
c0102807:	8b 40 44             	mov    0x44(%eax),%eax
c010280a:	83 e8 44             	sub    $0x44,%eax
c010280d:	a3 cc b7 12 c0       	mov    %eax,0xc012b7cc
            //使用 memmove 将当前的陷阱框架（除了最后8个字节）复制到新的陷阱框架位置 switchu2k
            memmove(switchu2k, tf, sizeof(struct trapframe) - 8);
c0102812:	a1 cc b7 12 c0       	mov    0xc012b7cc,%eax
c0102817:	c7 44 24 08 44 00 00 	movl   $0x44,0x8(%esp)
c010281e:	00 
c010281f:	8b 55 08             	mov    0x8(%ebp),%edx
c0102822:	89 54 24 04          	mov    %edx,0x4(%esp)
c0102826:	89 04 24             	mov    %eax,(%esp)
c0102829:	e8 f8 76 00 00       	call   c0109f26 <memmove>
            //将新的陷阱框架地址 switchu2k 存储到当前陷阱框架之前的一个栈位置
            *((uint32_t *)tf - 1) = (uint32_t)switchu2k;
c010282e:	8b 15 cc b7 12 c0    	mov    0xc012b7cc,%edx
c0102834:	8b 45 08             	mov    0x8(%ebp),%eax
c0102837:	83 e8 04             	sub    $0x4,%eax
c010283a:	89 10                	mov    %edx,(%eax)
        }
        break;
c010283c:	eb 41                	jmp    c010287f <trap_dispatch+0x278>
        break;
    default:
        // in kernel, it must be a mistake
        //检查当前陷阱框架的代码段寄存器 tf->tf_cs 的特权级
        //(tf->tf_cs & 3) == 0 检查是否在内核模式中
        if ((tf->tf_cs & 3) == 0) {
c010283e:	8b 45 08             	mov    0x8(%ebp),%eax
c0102841:	0f b7 40 3c          	movzwl 0x3c(%eax),%eax
c0102845:	83 e0 03             	and    $0x3,%eax
c0102848:	85 c0                	test   %eax,%eax
c010284a:	75 34                	jne    c0102880 <trap_dispatch+0x279>
            print_trapframe(tf);
c010284c:	8b 45 08             	mov    0x8(%ebp),%eax
c010284f:	89 04 24             	mov    %eax,(%esp)
c0102852:	e8 62 fa ff ff       	call   c01022b9 <print_trapframe>
            panic("unexpected trap in kernel.\n");
c0102857:	c7 44 24 08 1b a7 10 	movl   $0xc010a71b,0x8(%esp)
c010285e:	c0 
c010285f:	c7 44 24 04 2f 01 00 	movl   $0x12f,0x4(%esp)
c0102866:	00 
c0102867:	c7 04 24 ce a6 10 c0 	movl   $0xc010a6ce,(%esp)
c010286e:	e8 d2 e3 ff ff       	call   c0100c45 <__panic>
        break;
c0102873:	90                   	nop
c0102874:	eb 0a                	jmp    c0102880 <trap_dispatch+0x279>
        break;
c0102876:	90                   	nop
c0102877:	eb 07                	jmp    c0102880 <trap_dispatch+0x279>
        break;
c0102879:	90                   	nop
c010287a:	eb 04                	jmp    c0102880 <trap_dispatch+0x279>
        break;
c010287c:	90                   	nop
c010287d:	eb 01                	jmp    c0102880 <trap_dispatch+0x279>
        break;
c010287f:	90                   	nop
        }
    }
}
c0102880:	90                   	nop
c0102881:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c0102884:	89 ec                	mov    %ebp,%esp
c0102886:	5d                   	pop    %ebp
c0102887:	c3                   	ret    

c0102888 <trap>:
 * trap - handles or dispatches an exception/interrupt. if and when trap() returns,
 * the code in kern/trap/trapentry.S restores the old CPU state saved in the
 * trapframe and then uses the iret instruction to return from the exception.
 * */
void
trap(struct trapframe *tf) {
c0102888:	55                   	push   %ebp
c0102889:	89 e5                	mov    %esp,%ebp
c010288b:	83 ec 18             	sub    $0x18,%esp
    // dispatch based on what type of trap occurred
    //该行代码调用 trap_dispatch 函数，将陷阱帧传递给它。
    trap_dispatch(tf);
c010288e:	8b 45 08             	mov    0x8(%ebp),%eax
c0102891:	89 04 24             	mov    %eax,(%esp)
c0102894:	e8 6e fd ff ff       	call   c0102607 <trap_dispatch>
}
c0102899:	90                   	nop
c010289a:	89 ec                	mov    %ebp,%esp
c010289c:	5d                   	pop    %ebp
c010289d:	c3                   	ret    

c010289e <__alltraps>:
.globl __alltraps
__alltraps:
    # push registers to build a trap frame
    # therefore make the stack look like a struct trapframe
    # 通过 push 指令，将数据段寄存器和所有通用寄存器（使用 pushal）的值压入栈中，以保存当前状态。
    pushl %ds
c010289e:	1e                   	push   %ds
    pushl %es
c010289f:	06                   	push   %es
    pushl %fs
c01028a0:	0f a0                	push   %fs
    pushl %gs
c01028a2:	0f a8                	push   %gs
    pushal
c01028a4:	60                   	pusha  

    # load GD_KDATA into %ds and %es to set up data segments for kernel
    # 将常量 GD_KDATA 加载到 %eax 中，然后将其值复制到 %ds 和 %es 中，设置内核的数据段。
    movl $GD_KDATA, %eax
c01028a5:	b8 10 00 00 00       	mov    $0x10,%eax
    movw %ax, %ds
c01028aa:	8e d8                	mov    %eax,%ds
    movw %ax, %es
c01028ac:	8e c0                	mov    %eax,%es

    # push %esp to pass a pointer to the trapframe as an argument to trap()
    # 将 %esp 压栈，以将指向 trapframe 的指针作为参数传递给 trap()
    pushl %esp
c01028ae:	54                   	push   %esp

    # call trap(tf), where tf=%esp
    # 调用 trap(tf)，其中 tf=%esp
    call trap
c01028af:	e8 d4 ff ff ff       	call   c0102888 <trap>

    # pop the pushed stack pointer弹出之前压入的栈指针
    popl %esp
c01028b4:	5c                   	pop    %esp

c01028b5 <__trapret>:
    # 返回后继续执行到 trapret...
.globl __trapret
__trapret:
    # restore registers from stack
    # 定义了返回的入口点 __trapret。
    popal
c01028b5:	61                   	popa   

    # restore %ds, %es, %fs and %gs
    # 这里会恢复之前保存的寄存器
    popl %gs
c01028b6:	0f a9                	pop    %gs
    popl %fs
c01028b8:	0f a1                	pop    %fs
    popl %es
c01028ba:	07                   	pop    %es
    popl %ds
c01028bb:	1f                   	pop    %ds

    # get rid of the trap number and error code
    # 通过 iret 指令返回中断处理
    addl $0x8, %esp
c01028bc:	83 c4 08             	add    $0x8,%esp
    iret
c01028bf:	cf                   	iret   

c01028c0 <forkrets>:

.globl forkrets
forkrets:
    # set stack to this new process's trapframe
    movl 4(%esp), %esp
c01028c0:	8b 64 24 04          	mov    0x4(%esp),%esp
    jmp __trapret
c01028c4:	eb ef                	jmp    c01028b5 <__trapret>

c01028c6 <vector0>:
# handler
.text
.globl __alltraps
.globl vector0
vector0:
  pushl $0
c01028c6:	6a 00                	push   $0x0
  pushl $0
c01028c8:	6a 00                	push   $0x0
  jmp __alltraps
c01028ca:	e9 cf ff ff ff       	jmp    c010289e <__alltraps>

c01028cf <vector1>:
.globl vector1
vector1:
  pushl $0
c01028cf:	6a 00                	push   $0x0
  pushl $1
c01028d1:	6a 01                	push   $0x1
  jmp __alltraps
c01028d3:	e9 c6 ff ff ff       	jmp    c010289e <__alltraps>

c01028d8 <vector2>:
.globl vector2
vector2:
  pushl $0
c01028d8:	6a 00                	push   $0x0
  pushl $2
c01028da:	6a 02                	push   $0x2
  jmp __alltraps
c01028dc:	e9 bd ff ff ff       	jmp    c010289e <__alltraps>

c01028e1 <vector3>:
.globl vector3
vector3:
  pushl $0
c01028e1:	6a 00                	push   $0x0
  pushl $3
c01028e3:	6a 03                	push   $0x3
  jmp __alltraps
c01028e5:	e9 b4 ff ff ff       	jmp    c010289e <__alltraps>

c01028ea <vector4>:
.globl vector4
vector4:
  pushl $0
c01028ea:	6a 00                	push   $0x0
  pushl $4
c01028ec:	6a 04                	push   $0x4
  jmp __alltraps
c01028ee:	e9 ab ff ff ff       	jmp    c010289e <__alltraps>

c01028f3 <vector5>:
.globl vector5
vector5:
  pushl $0
c01028f3:	6a 00                	push   $0x0
  pushl $5
c01028f5:	6a 05                	push   $0x5
  jmp __alltraps
c01028f7:	e9 a2 ff ff ff       	jmp    c010289e <__alltraps>

c01028fc <vector6>:
.globl vector6
vector6:
  pushl $0
c01028fc:	6a 00                	push   $0x0
  pushl $6
c01028fe:	6a 06                	push   $0x6
  jmp __alltraps
c0102900:	e9 99 ff ff ff       	jmp    c010289e <__alltraps>

c0102905 <vector7>:
.globl vector7
vector7:
  pushl $0
c0102905:	6a 00                	push   $0x0
  pushl $7
c0102907:	6a 07                	push   $0x7
  jmp __alltraps
c0102909:	e9 90 ff ff ff       	jmp    c010289e <__alltraps>

c010290e <vector8>:
.globl vector8
vector8:
  pushl $8
c010290e:	6a 08                	push   $0x8
  jmp __alltraps
c0102910:	e9 89 ff ff ff       	jmp    c010289e <__alltraps>

c0102915 <vector9>:
.globl vector9
vector9:
  pushl $0
c0102915:	6a 00                	push   $0x0
  pushl $9
c0102917:	6a 09                	push   $0x9
  jmp __alltraps
c0102919:	e9 80 ff ff ff       	jmp    c010289e <__alltraps>

c010291e <vector10>:
.globl vector10
vector10:
  pushl $10
c010291e:	6a 0a                	push   $0xa
  jmp __alltraps
c0102920:	e9 79 ff ff ff       	jmp    c010289e <__alltraps>

c0102925 <vector11>:
.globl vector11
vector11:
  pushl $11
c0102925:	6a 0b                	push   $0xb
  jmp __alltraps
c0102927:	e9 72 ff ff ff       	jmp    c010289e <__alltraps>

c010292c <vector12>:
.globl vector12
vector12:
  pushl $12
c010292c:	6a 0c                	push   $0xc
  jmp __alltraps
c010292e:	e9 6b ff ff ff       	jmp    c010289e <__alltraps>

c0102933 <vector13>:
.globl vector13
vector13:
  pushl $13
c0102933:	6a 0d                	push   $0xd
  jmp __alltraps
c0102935:	e9 64 ff ff ff       	jmp    c010289e <__alltraps>

c010293a <vector14>:
.globl vector14
vector14:
  pushl $14
c010293a:	6a 0e                	push   $0xe
  jmp __alltraps
c010293c:	e9 5d ff ff ff       	jmp    c010289e <__alltraps>

c0102941 <vector15>:
.globl vector15
vector15:
  pushl $0
c0102941:	6a 00                	push   $0x0
  pushl $15
c0102943:	6a 0f                	push   $0xf
  jmp __alltraps
c0102945:	e9 54 ff ff ff       	jmp    c010289e <__alltraps>

c010294a <vector16>:
.globl vector16
vector16:
  pushl $0
c010294a:	6a 00                	push   $0x0
  pushl $16
c010294c:	6a 10                	push   $0x10
  jmp __alltraps
c010294e:	e9 4b ff ff ff       	jmp    c010289e <__alltraps>

c0102953 <vector17>:
.globl vector17
vector17:
  pushl $17
c0102953:	6a 11                	push   $0x11
  jmp __alltraps
c0102955:	e9 44 ff ff ff       	jmp    c010289e <__alltraps>

c010295a <vector18>:
.globl vector18
vector18:
  pushl $0
c010295a:	6a 00                	push   $0x0
  pushl $18
c010295c:	6a 12                	push   $0x12
  jmp __alltraps
c010295e:	e9 3b ff ff ff       	jmp    c010289e <__alltraps>

c0102963 <vector19>:
.globl vector19
vector19:
  pushl $0
c0102963:	6a 00                	push   $0x0
  pushl $19
c0102965:	6a 13                	push   $0x13
  jmp __alltraps
c0102967:	e9 32 ff ff ff       	jmp    c010289e <__alltraps>

c010296c <vector20>:
.globl vector20
vector20:
  pushl $0
c010296c:	6a 00                	push   $0x0
  pushl $20
c010296e:	6a 14                	push   $0x14
  jmp __alltraps
c0102970:	e9 29 ff ff ff       	jmp    c010289e <__alltraps>

c0102975 <vector21>:
.globl vector21
vector21:
  pushl $0
c0102975:	6a 00                	push   $0x0
  pushl $21
c0102977:	6a 15                	push   $0x15
  jmp __alltraps
c0102979:	e9 20 ff ff ff       	jmp    c010289e <__alltraps>

c010297e <vector22>:
.globl vector22
vector22:
  pushl $0
c010297e:	6a 00                	push   $0x0
  pushl $22
c0102980:	6a 16                	push   $0x16
  jmp __alltraps
c0102982:	e9 17 ff ff ff       	jmp    c010289e <__alltraps>

c0102987 <vector23>:
.globl vector23
vector23:
  pushl $0
c0102987:	6a 00                	push   $0x0
  pushl $23
c0102989:	6a 17                	push   $0x17
  jmp __alltraps
c010298b:	e9 0e ff ff ff       	jmp    c010289e <__alltraps>

c0102990 <vector24>:
.globl vector24
vector24:
  pushl $0
c0102990:	6a 00                	push   $0x0
  pushl $24
c0102992:	6a 18                	push   $0x18
  jmp __alltraps
c0102994:	e9 05 ff ff ff       	jmp    c010289e <__alltraps>

c0102999 <vector25>:
.globl vector25
vector25:
  pushl $0
c0102999:	6a 00                	push   $0x0
  pushl $25
c010299b:	6a 19                	push   $0x19
  jmp __alltraps
c010299d:	e9 fc fe ff ff       	jmp    c010289e <__alltraps>

c01029a2 <vector26>:
.globl vector26
vector26:
  pushl $0
c01029a2:	6a 00                	push   $0x0
  pushl $26
c01029a4:	6a 1a                	push   $0x1a
  jmp __alltraps
c01029a6:	e9 f3 fe ff ff       	jmp    c010289e <__alltraps>

c01029ab <vector27>:
.globl vector27
vector27:
  pushl $0
c01029ab:	6a 00                	push   $0x0
  pushl $27
c01029ad:	6a 1b                	push   $0x1b
  jmp __alltraps
c01029af:	e9 ea fe ff ff       	jmp    c010289e <__alltraps>

c01029b4 <vector28>:
.globl vector28
vector28:
  pushl $0
c01029b4:	6a 00                	push   $0x0
  pushl $28
c01029b6:	6a 1c                	push   $0x1c
  jmp __alltraps
c01029b8:	e9 e1 fe ff ff       	jmp    c010289e <__alltraps>

c01029bd <vector29>:
.globl vector29
vector29:
  pushl $0
c01029bd:	6a 00                	push   $0x0
  pushl $29
c01029bf:	6a 1d                	push   $0x1d
  jmp __alltraps
c01029c1:	e9 d8 fe ff ff       	jmp    c010289e <__alltraps>

c01029c6 <vector30>:
.globl vector30
vector30:
  pushl $0
c01029c6:	6a 00                	push   $0x0
  pushl $30
c01029c8:	6a 1e                	push   $0x1e
  jmp __alltraps
c01029ca:	e9 cf fe ff ff       	jmp    c010289e <__alltraps>

c01029cf <vector31>:
.globl vector31
vector31:
  pushl $0
c01029cf:	6a 00                	push   $0x0
  pushl $31
c01029d1:	6a 1f                	push   $0x1f
  jmp __alltraps
c01029d3:	e9 c6 fe ff ff       	jmp    c010289e <__alltraps>

c01029d8 <vector32>:
.globl vector32
vector32:
  pushl $0
c01029d8:	6a 00                	push   $0x0
  pushl $32
c01029da:	6a 20                	push   $0x20
  jmp __alltraps
c01029dc:	e9 bd fe ff ff       	jmp    c010289e <__alltraps>

c01029e1 <vector33>:
.globl vector33
vector33:
  pushl $0
c01029e1:	6a 00                	push   $0x0
  pushl $33
c01029e3:	6a 21                	push   $0x21
  jmp __alltraps
c01029e5:	e9 b4 fe ff ff       	jmp    c010289e <__alltraps>

c01029ea <vector34>:
.globl vector34
vector34:
  pushl $0
c01029ea:	6a 00                	push   $0x0
  pushl $34
c01029ec:	6a 22                	push   $0x22
  jmp __alltraps
c01029ee:	e9 ab fe ff ff       	jmp    c010289e <__alltraps>

c01029f3 <vector35>:
.globl vector35
vector35:
  pushl $0
c01029f3:	6a 00                	push   $0x0
  pushl $35
c01029f5:	6a 23                	push   $0x23
  jmp __alltraps
c01029f7:	e9 a2 fe ff ff       	jmp    c010289e <__alltraps>

c01029fc <vector36>:
.globl vector36
vector36:
  pushl $0
c01029fc:	6a 00                	push   $0x0
  pushl $36
c01029fe:	6a 24                	push   $0x24
  jmp __alltraps
c0102a00:	e9 99 fe ff ff       	jmp    c010289e <__alltraps>

c0102a05 <vector37>:
.globl vector37
vector37:
  pushl $0
c0102a05:	6a 00                	push   $0x0
  pushl $37
c0102a07:	6a 25                	push   $0x25
  jmp __alltraps
c0102a09:	e9 90 fe ff ff       	jmp    c010289e <__alltraps>

c0102a0e <vector38>:
.globl vector38
vector38:
  pushl $0
c0102a0e:	6a 00                	push   $0x0
  pushl $38
c0102a10:	6a 26                	push   $0x26
  jmp __alltraps
c0102a12:	e9 87 fe ff ff       	jmp    c010289e <__alltraps>

c0102a17 <vector39>:
.globl vector39
vector39:
  pushl $0
c0102a17:	6a 00                	push   $0x0
  pushl $39
c0102a19:	6a 27                	push   $0x27
  jmp __alltraps
c0102a1b:	e9 7e fe ff ff       	jmp    c010289e <__alltraps>

c0102a20 <vector40>:
.globl vector40
vector40:
  pushl $0
c0102a20:	6a 00                	push   $0x0
  pushl $40
c0102a22:	6a 28                	push   $0x28
  jmp __alltraps
c0102a24:	e9 75 fe ff ff       	jmp    c010289e <__alltraps>

c0102a29 <vector41>:
.globl vector41
vector41:
  pushl $0
c0102a29:	6a 00                	push   $0x0
  pushl $41
c0102a2b:	6a 29                	push   $0x29
  jmp __alltraps
c0102a2d:	e9 6c fe ff ff       	jmp    c010289e <__alltraps>

c0102a32 <vector42>:
.globl vector42
vector42:
  pushl $0
c0102a32:	6a 00                	push   $0x0
  pushl $42
c0102a34:	6a 2a                	push   $0x2a
  jmp __alltraps
c0102a36:	e9 63 fe ff ff       	jmp    c010289e <__alltraps>

c0102a3b <vector43>:
.globl vector43
vector43:
  pushl $0
c0102a3b:	6a 00                	push   $0x0
  pushl $43
c0102a3d:	6a 2b                	push   $0x2b
  jmp __alltraps
c0102a3f:	e9 5a fe ff ff       	jmp    c010289e <__alltraps>

c0102a44 <vector44>:
.globl vector44
vector44:
  pushl $0
c0102a44:	6a 00                	push   $0x0
  pushl $44
c0102a46:	6a 2c                	push   $0x2c
  jmp __alltraps
c0102a48:	e9 51 fe ff ff       	jmp    c010289e <__alltraps>

c0102a4d <vector45>:
.globl vector45
vector45:
  pushl $0
c0102a4d:	6a 00                	push   $0x0
  pushl $45
c0102a4f:	6a 2d                	push   $0x2d
  jmp __alltraps
c0102a51:	e9 48 fe ff ff       	jmp    c010289e <__alltraps>

c0102a56 <vector46>:
.globl vector46
vector46:
  pushl $0
c0102a56:	6a 00                	push   $0x0
  pushl $46
c0102a58:	6a 2e                	push   $0x2e
  jmp __alltraps
c0102a5a:	e9 3f fe ff ff       	jmp    c010289e <__alltraps>

c0102a5f <vector47>:
.globl vector47
vector47:
  pushl $0
c0102a5f:	6a 00                	push   $0x0
  pushl $47
c0102a61:	6a 2f                	push   $0x2f
  jmp __alltraps
c0102a63:	e9 36 fe ff ff       	jmp    c010289e <__alltraps>

c0102a68 <vector48>:
.globl vector48
vector48:
  pushl $0
c0102a68:	6a 00                	push   $0x0
  pushl $48
c0102a6a:	6a 30                	push   $0x30
  jmp __alltraps
c0102a6c:	e9 2d fe ff ff       	jmp    c010289e <__alltraps>

c0102a71 <vector49>:
.globl vector49
vector49:
  pushl $0
c0102a71:	6a 00                	push   $0x0
  pushl $49
c0102a73:	6a 31                	push   $0x31
  jmp __alltraps
c0102a75:	e9 24 fe ff ff       	jmp    c010289e <__alltraps>

c0102a7a <vector50>:
.globl vector50
vector50:
  pushl $0
c0102a7a:	6a 00                	push   $0x0
  pushl $50
c0102a7c:	6a 32                	push   $0x32
  jmp __alltraps
c0102a7e:	e9 1b fe ff ff       	jmp    c010289e <__alltraps>

c0102a83 <vector51>:
.globl vector51
vector51:
  pushl $0
c0102a83:	6a 00                	push   $0x0
  pushl $51
c0102a85:	6a 33                	push   $0x33
  jmp __alltraps
c0102a87:	e9 12 fe ff ff       	jmp    c010289e <__alltraps>

c0102a8c <vector52>:
.globl vector52
vector52:
  pushl $0
c0102a8c:	6a 00                	push   $0x0
  pushl $52
c0102a8e:	6a 34                	push   $0x34
  jmp __alltraps
c0102a90:	e9 09 fe ff ff       	jmp    c010289e <__alltraps>

c0102a95 <vector53>:
.globl vector53
vector53:
  pushl $0
c0102a95:	6a 00                	push   $0x0
  pushl $53
c0102a97:	6a 35                	push   $0x35
  jmp __alltraps
c0102a99:	e9 00 fe ff ff       	jmp    c010289e <__alltraps>

c0102a9e <vector54>:
.globl vector54
vector54:
  pushl $0
c0102a9e:	6a 00                	push   $0x0
  pushl $54
c0102aa0:	6a 36                	push   $0x36
  jmp __alltraps
c0102aa2:	e9 f7 fd ff ff       	jmp    c010289e <__alltraps>

c0102aa7 <vector55>:
.globl vector55
vector55:
  pushl $0
c0102aa7:	6a 00                	push   $0x0
  pushl $55
c0102aa9:	6a 37                	push   $0x37
  jmp __alltraps
c0102aab:	e9 ee fd ff ff       	jmp    c010289e <__alltraps>

c0102ab0 <vector56>:
.globl vector56
vector56:
  pushl $0
c0102ab0:	6a 00                	push   $0x0
  pushl $56
c0102ab2:	6a 38                	push   $0x38
  jmp __alltraps
c0102ab4:	e9 e5 fd ff ff       	jmp    c010289e <__alltraps>

c0102ab9 <vector57>:
.globl vector57
vector57:
  pushl $0
c0102ab9:	6a 00                	push   $0x0
  pushl $57
c0102abb:	6a 39                	push   $0x39
  jmp __alltraps
c0102abd:	e9 dc fd ff ff       	jmp    c010289e <__alltraps>

c0102ac2 <vector58>:
.globl vector58
vector58:
  pushl $0
c0102ac2:	6a 00                	push   $0x0
  pushl $58
c0102ac4:	6a 3a                	push   $0x3a
  jmp __alltraps
c0102ac6:	e9 d3 fd ff ff       	jmp    c010289e <__alltraps>

c0102acb <vector59>:
.globl vector59
vector59:
  pushl $0
c0102acb:	6a 00                	push   $0x0
  pushl $59
c0102acd:	6a 3b                	push   $0x3b
  jmp __alltraps
c0102acf:	e9 ca fd ff ff       	jmp    c010289e <__alltraps>

c0102ad4 <vector60>:
.globl vector60
vector60:
  pushl $0
c0102ad4:	6a 00                	push   $0x0
  pushl $60
c0102ad6:	6a 3c                	push   $0x3c
  jmp __alltraps
c0102ad8:	e9 c1 fd ff ff       	jmp    c010289e <__alltraps>

c0102add <vector61>:
.globl vector61
vector61:
  pushl $0
c0102add:	6a 00                	push   $0x0
  pushl $61
c0102adf:	6a 3d                	push   $0x3d
  jmp __alltraps
c0102ae1:	e9 b8 fd ff ff       	jmp    c010289e <__alltraps>

c0102ae6 <vector62>:
.globl vector62
vector62:
  pushl $0
c0102ae6:	6a 00                	push   $0x0
  pushl $62
c0102ae8:	6a 3e                	push   $0x3e
  jmp __alltraps
c0102aea:	e9 af fd ff ff       	jmp    c010289e <__alltraps>

c0102aef <vector63>:
.globl vector63
vector63:
  pushl $0
c0102aef:	6a 00                	push   $0x0
  pushl $63
c0102af1:	6a 3f                	push   $0x3f
  jmp __alltraps
c0102af3:	e9 a6 fd ff ff       	jmp    c010289e <__alltraps>

c0102af8 <vector64>:
.globl vector64
vector64:
  pushl $0
c0102af8:	6a 00                	push   $0x0
  pushl $64
c0102afa:	6a 40                	push   $0x40
  jmp __alltraps
c0102afc:	e9 9d fd ff ff       	jmp    c010289e <__alltraps>

c0102b01 <vector65>:
.globl vector65
vector65:
  pushl $0
c0102b01:	6a 00                	push   $0x0
  pushl $65
c0102b03:	6a 41                	push   $0x41
  jmp __alltraps
c0102b05:	e9 94 fd ff ff       	jmp    c010289e <__alltraps>

c0102b0a <vector66>:
.globl vector66
vector66:
  pushl $0
c0102b0a:	6a 00                	push   $0x0
  pushl $66
c0102b0c:	6a 42                	push   $0x42
  jmp __alltraps
c0102b0e:	e9 8b fd ff ff       	jmp    c010289e <__alltraps>

c0102b13 <vector67>:
.globl vector67
vector67:
  pushl $0
c0102b13:	6a 00                	push   $0x0
  pushl $67
c0102b15:	6a 43                	push   $0x43
  jmp __alltraps
c0102b17:	e9 82 fd ff ff       	jmp    c010289e <__alltraps>

c0102b1c <vector68>:
.globl vector68
vector68:
  pushl $0
c0102b1c:	6a 00                	push   $0x0
  pushl $68
c0102b1e:	6a 44                	push   $0x44
  jmp __alltraps
c0102b20:	e9 79 fd ff ff       	jmp    c010289e <__alltraps>

c0102b25 <vector69>:
.globl vector69
vector69:
  pushl $0
c0102b25:	6a 00                	push   $0x0
  pushl $69
c0102b27:	6a 45                	push   $0x45
  jmp __alltraps
c0102b29:	e9 70 fd ff ff       	jmp    c010289e <__alltraps>

c0102b2e <vector70>:
.globl vector70
vector70:
  pushl $0
c0102b2e:	6a 00                	push   $0x0
  pushl $70
c0102b30:	6a 46                	push   $0x46
  jmp __alltraps
c0102b32:	e9 67 fd ff ff       	jmp    c010289e <__alltraps>

c0102b37 <vector71>:
.globl vector71
vector71:
  pushl $0
c0102b37:	6a 00                	push   $0x0
  pushl $71
c0102b39:	6a 47                	push   $0x47
  jmp __alltraps
c0102b3b:	e9 5e fd ff ff       	jmp    c010289e <__alltraps>

c0102b40 <vector72>:
.globl vector72
vector72:
  pushl $0
c0102b40:	6a 00                	push   $0x0
  pushl $72
c0102b42:	6a 48                	push   $0x48
  jmp __alltraps
c0102b44:	e9 55 fd ff ff       	jmp    c010289e <__alltraps>

c0102b49 <vector73>:
.globl vector73
vector73:
  pushl $0
c0102b49:	6a 00                	push   $0x0
  pushl $73
c0102b4b:	6a 49                	push   $0x49
  jmp __alltraps
c0102b4d:	e9 4c fd ff ff       	jmp    c010289e <__alltraps>

c0102b52 <vector74>:
.globl vector74
vector74:
  pushl $0
c0102b52:	6a 00                	push   $0x0
  pushl $74
c0102b54:	6a 4a                	push   $0x4a
  jmp __alltraps
c0102b56:	e9 43 fd ff ff       	jmp    c010289e <__alltraps>

c0102b5b <vector75>:
.globl vector75
vector75:
  pushl $0
c0102b5b:	6a 00                	push   $0x0
  pushl $75
c0102b5d:	6a 4b                	push   $0x4b
  jmp __alltraps
c0102b5f:	e9 3a fd ff ff       	jmp    c010289e <__alltraps>

c0102b64 <vector76>:
.globl vector76
vector76:
  pushl $0
c0102b64:	6a 00                	push   $0x0
  pushl $76
c0102b66:	6a 4c                	push   $0x4c
  jmp __alltraps
c0102b68:	e9 31 fd ff ff       	jmp    c010289e <__alltraps>

c0102b6d <vector77>:
.globl vector77
vector77:
  pushl $0
c0102b6d:	6a 00                	push   $0x0
  pushl $77
c0102b6f:	6a 4d                	push   $0x4d
  jmp __alltraps
c0102b71:	e9 28 fd ff ff       	jmp    c010289e <__alltraps>

c0102b76 <vector78>:
.globl vector78
vector78:
  pushl $0
c0102b76:	6a 00                	push   $0x0
  pushl $78
c0102b78:	6a 4e                	push   $0x4e
  jmp __alltraps
c0102b7a:	e9 1f fd ff ff       	jmp    c010289e <__alltraps>

c0102b7f <vector79>:
.globl vector79
vector79:
  pushl $0
c0102b7f:	6a 00                	push   $0x0
  pushl $79
c0102b81:	6a 4f                	push   $0x4f
  jmp __alltraps
c0102b83:	e9 16 fd ff ff       	jmp    c010289e <__alltraps>

c0102b88 <vector80>:
.globl vector80
vector80:
  pushl $0
c0102b88:	6a 00                	push   $0x0
  pushl $80
c0102b8a:	6a 50                	push   $0x50
  jmp __alltraps
c0102b8c:	e9 0d fd ff ff       	jmp    c010289e <__alltraps>

c0102b91 <vector81>:
.globl vector81
vector81:
  pushl $0
c0102b91:	6a 00                	push   $0x0
  pushl $81
c0102b93:	6a 51                	push   $0x51
  jmp __alltraps
c0102b95:	e9 04 fd ff ff       	jmp    c010289e <__alltraps>

c0102b9a <vector82>:
.globl vector82
vector82:
  pushl $0
c0102b9a:	6a 00                	push   $0x0
  pushl $82
c0102b9c:	6a 52                	push   $0x52
  jmp __alltraps
c0102b9e:	e9 fb fc ff ff       	jmp    c010289e <__alltraps>

c0102ba3 <vector83>:
.globl vector83
vector83:
  pushl $0
c0102ba3:	6a 00                	push   $0x0
  pushl $83
c0102ba5:	6a 53                	push   $0x53
  jmp __alltraps
c0102ba7:	e9 f2 fc ff ff       	jmp    c010289e <__alltraps>

c0102bac <vector84>:
.globl vector84
vector84:
  pushl $0
c0102bac:	6a 00                	push   $0x0
  pushl $84
c0102bae:	6a 54                	push   $0x54
  jmp __alltraps
c0102bb0:	e9 e9 fc ff ff       	jmp    c010289e <__alltraps>

c0102bb5 <vector85>:
.globl vector85
vector85:
  pushl $0
c0102bb5:	6a 00                	push   $0x0
  pushl $85
c0102bb7:	6a 55                	push   $0x55
  jmp __alltraps
c0102bb9:	e9 e0 fc ff ff       	jmp    c010289e <__alltraps>

c0102bbe <vector86>:
.globl vector86
vector86:
  pushl $0
c0102bbe:	6a 00                	push   $0x0
  pushl $86
c0102bc0:	6a 56                	push   $0x56
  jmp __alltraps
c0102bc2:	e9 d7 fc ff ff       	jmp    c010289e <__alltraps>

c0102bc7 <vector87>:
.globl vector87
vector87:
  pushl $0
c0102bc7:	6a 00                	push   $0x0
  pushl $87
c0102bc9:	6a 57                	push   $0x57
  jmp __alltraps
c0102bcb:	e9 ce fc ff ff       	jmp    c010289e <__alltraps>

c0102bd0 <vector88>:
.globl vector88
vector88:
  pushl $0
c0102bd0:	6a 00                	push   $0x0
  pushl $88
c0102bd2:	6a 58                	push   $0x58
  jmp __alltraps
c0102bd4:	e9 c5 fc ff ff       	jmp    c010289e <__alltraps>

c0102bd9 <vector89>:
.globl vector89
vector89:
  pushl $0
c0102bd9:	6a 00                	push   $0x0
  pushl $89
c0102bdb:	6a 59                	push   $0x59
  jmp __alltraps
c0102bdd:	e9 bc fc ff ff       	jmp    c010289e <__alltraps>

c0102be2 <vector90>:
.globl vector90
vector90:
  pushl $0
c0102be2:	6a 00                	push   $0x0
  pushl $90
c0102be4:	6a 5a                	push   $0x5a
  jmp __alltraps
c0102be6:	e9 b3 fc ff ff       	jmp    c010289e <__alltraps>

c0102beb <vector91>:
.globl vector91
vector91:
  pushl $0
c0102beb:	6a 00                	push   $0x0
  pushl $91
c0102bed:	6a 5b                	push   $0x5b
  jmp __alltraps
c0102bef:	e9 aa fc ff ff       	jmp    c010289e <__alltraps>

c0102bf4 <vector92>:
.globl vector92
vector92:
  pushl $0
c0102bf4:	6a 00                	push   $0x0
  pushl $92
c0102bf6:	6a 5c                	push   $0x5c
  jmp __alltraps
c0102bf8:	e9 a1 fc ff ff       	jmp    c010289e <__alltraps>

c0102bfd <vector93>:
.globl vector93
vector93:
  pushl $0
c0102bfd:	6a 00                	push   $0x0
  pushl $93
c0102bff:	6a 5d                	push   $0x5d
  jmp __alltraps
c0102c01:	e9 98 fc ff ff       	jmp    c010289e <__alltraps>

c0102c06 <vector94>:
.globl vector94
vector94:
  pushl $0
c0102c06:	6a 00                	push   $0x0
  pushl $94
c0102c08:	6a 5e                	push   $0x5e
  jmp __alltraps
c0102c0a:	e9 8f fc ff ff       	jmp    c010289e <__alltraps>

c0102c0f <vector95>:
.globl vector95
vector95:
  pushl $0
c0102c0f:	6a 00                	push   $0x0
  pushl $95
c0102c11:	6a 5f                	push   $0x5f
  jmp __alltraps
c0102c13:	e9 86 fc ff ff       	jmp    c010289e <__alltraps>

c0102c18 <vector96>:
.globl vector96
vector96:
  pushl $0
c0102c18:	6a 00                	push   $0x0
  pushl $96
c0102c1a:	6a 60                	push   $0x60
  jmp __alltraps
c0102c1c:	e9 7d fc ff ff       	jmp    c010289e <__alltraps>

c0102c21 <vector97>:
.globl vector97
vector97:
  pushl $0
c0102c21:	6a 00                	push   $0x0
  pushl $97
c0102c23:	6a 61                	push   $0x61
  jmp __alltraps
c0102c25:	e9 74 fc ff ff       	jmp    c010289e <__alltraps>

c0102c2a <vector98>:
.globl vector98
vector98:
  pushl $0
c0102c2a:	6a 00                	push   $0x0
  pushl $98
c0102c2c:	6a 62                	push   $0x62
  jmp __alltraps
c0102c2e:	e9 6b fc ff ff       	jmp    c010289e <__alltraps>

c0102c33 <vector99>:
.globl vector99
vector99:
  pushl $0
c0102c33:	6a 00                	push   $0x0
  pushl $99
c0102c35:	6a 63                	push   $0x63
  jmp __alltraps
c0102c37:	e9 62 fc ff ff       	jmp    c010289e <__alltraps>

c0102c3c <vector100>:
.globl vector100
vector100:
  pushl $0
c0102c3c:	6a 00                	push   $0x0
  pushl $100
c0102c3e:	6a 64                	push   $0x64
  jmp __alltraps
c0102c40:	e9 59 fc ff ff       	jmp    c010289e <__alltraps>

c0102c45 <vector101>:
.globl vector101
vector101:
  pushl $0
c0102c45:	6a 00                	push   $0x0
  pushl $101
c0102c47:	6a 65                	push   $0x65
  jmp __alltraps
c0102c49:	e9 50 fc ff ff       	jmp    c010289e <__alltraps>

c0102c4e <vector102>:
.globl vector102
vector102:
  pushl $0
c0102c4e:	6a 00                	push   $0x0
  pushl $102
c0102c50:	6a 66                	push   $0x66
  jmp __alltraps
c0102c52:	e9 47 fc ff ff       	jmp    c010289e <__alltraps>

c0102c57 <vector103>:
.globl vector103
vector103:
  pushl $0
c0102c57:	6a 00                	push   $0x0
  pushl $103
c0102c59:	6a 67                	push   $0x67
  jmp __alltraps
c0102c5b:	e9 3e fc ff ff       	jmp    c010289e <__alltraps>

c0102c60 <vector104>:
.globl vector104
vector104:
  pushl $0
c0102c60:	6a 00                	push   $0x0
  pushl $104
c0102c62:	6a 68                	push   $0x68
  jmp __alltraps
c0102c64:	e9 35 fc ff ff       	jmp    c010289e <__alltraps>

c0102c69 <vector105>:
.globl vector105
vector105:
  pushl $0
c0102c69:	6a 00                	push   $0x0
  pushl $105
c0102c6b:	6a 69                	push   $0x69
  jmp __alltraps
c0102c6d:	e9 2c fc ff ff       	jmp    c010289e <__alltraps>

c0102c72 <vector106>:
.globl vector106
vector106:
  pushl $0
c0102c72:	6a 00                	push   $0x0
  pushl $106
c0102c74:	6a 6a                	push   $0x6a
  jmp __alltraps
c0102c76:	e9 23 fc ff ff       	jmp    c010289e <__alltraps>

c0102c7b <vector107>:
.globl vector107
vector107:
  pushl $0
c0102c7b:	6a 00                	push   $0x0
  pushl $107
c0102c7d:	6a 6b                	push   $0x6b
  jmp __alltraps
c0102c7f:	e9 1a fc ff ff       	jmp    c010289e <__alltraps>

c0102c84 <vector108>:
.globl vector108
vector108:
  pushl $0
c0102c84:	6a 00                	push   $0x0
  pushl $108
c0102c86:	6a 6c                	push   $0x6c
  jmp __alltraps
c0102c88:	e9 11 fc ff ff       	jmp    c010289e <__alltraps>

c0102c8d <vector109>:
.globl vector109
vector109:
  pushl $0
c0102c8d:	6a 00                	push   $0x0
  pushl $109
c0102c8f:	6a 6d                	push   $0x6d
  jmp __alltraps
c0102c91:	e9 08 fc ff ff       	jmp    c010289e <__alltraps>

c0102c96 <vector110>:
.globl vector110
vector110:
  pushl $0
c0102c96:	6a 00                	push   $0x0
  pushl $110
c0102c98:	6a 6e                	push   $0x6e
  jmp __alltraps
c0102c9a:	e9 ff fb ff ff       	jmp    c010289e <__alltraps>

c0102c9f <vector111>:
.globl vector111
vector111:
  pushl $0
c0102c9f:	6a 00                	push   $0x0
  pushl $111
c0102ca1:	6a 6f                	push   $0x6f
  jmp __alltraps
c0102ca3:	e9 f6 fb ff ff       	jmp    c010289e <__alltraps>

c0102ca8 <vector112>:
.globl vector112
vector112:
  pushl $0
c0102ca8:	6a 00                	push   $0x0
  pushl $112
c0102caa:	6a 70                	push   $0x70
  jmp __alltraps
c0102cac:	e9 ed fb ff ff       	jmp    c010289e <__alltraps>

c0102cb1 <vector113>:
.globl vector113
vector113:
  pushl $0
c0102cb1:	6a 00                	push   $0x0
  pushl $113
c0102cb3:	6a 71                	push   $0x71
  jmp __alltraps
c0102cb5:	e9 e4 fb ff ff       	jmp    c010289e <__alltraps>

c0102cba <vector114>:
.globl vector114
vector114:
  pushl $0
c0102cba:	6a 00                	push   $0x0
  pushl $114
c0102cbc:	6a 72                	push   $0x72
  jmp __alltraps
c0102cbe:	e9 db fb ff ff       	jmp    c010289e <__alltraps>

c0102cc3 <vector115>:
.globl vector115
vector115:
  pushl $0
c0102cc3:	6a 00                	push   $0x0
  pushl $115
c0102cc5:	6a 73                	push   $0x73
  jmp __alltraps
c0102cc7:	e9 d2 fb ff ff       	jmp    c010289e <__alltraps>

c0102ccc <vector116>:
.globl vector116
vector116:
  pushl $0
c0102ccc:	6a 00                	push   $0x0
  pushl $116
c0102cce:	6a 74                	push   $0x74
  jmp __alltraps
c0102cd0:	e9 c9 fb ff ff       	jmp    c010289e <__alltraps>

c0102cd5 <vector117>:
.globl vector117
vector117:
  pushl $0
c0102cd5:	6a 00                	push   $0x0
  pushl $117
c0102cd7:	6a 75                	push   $0x75
  jmp __alltraps
c0102cd9:	e9 c0 fb ff ff       	jmp    c010289e <__alltraps>

c0102cde <vector118>:
.globl vector118
vector118:
  pushl $0
c0102cde:	6a 00                	push   $0x0
  pushl $118
c0102ce0:	6a 76                	push   $0x76
  jmp __alltraps
c0102ce2:	e9 b7 fb ff ff       	jmp    c010289e <__alltraps>

c0102ce7 <vector119>:
.globl vector119
vector119:
  pushl $0
c0102ce7:	6a 00                	push   $0x0
  pushl $119
c0102ce9:	6a 77                	push   $0x77
  jmp __alltraps
c0102ceb:	e9 ae fb ff ff       	jmp    c010289e <__alltraps>

c0102cf0 <vector120>:
.globl vector120
vector120:
  pushl $0
c0102cf0:	6a 00                	push   $0x0
  pushl $120
c0102cf2:	6a 78                	push   $0x78
  jmp __alltraps
c0102cf4:	e9 a5 fb ff ff       	jmp    c010289e <__alltraps>

c0102cf9 <vector121>:
.globl vector121
vector121:
  pushl $0
c0102cf9:	6a 00                	push   $0x0
  pushl $121
c0102cfb:	6a 79                	push   $0x79
  jmp __alltraps
c0102cfd:	e9 9c fb ff ff       	jmp    c010289e <__alltraps>

c0102d02 <vector122>:
.globl vector122
vector122:
  pushl $0
c0102d02:	6a 00                	push   $0x0
  pushl $122
c0102d04:	6a 7a                	push   $0x7a
  jmp __alltraps
c0102d06:	e9 93 fb ff ff       	jmp    c010289e <__alltraps>

c0102d0b <vector123>:
.globl vector123
vector123:
  pushl $0
c0102d0b:	6a 00                	push   $0x0
  pushl $123
c0102d0d:	6a 7b                	push   $0x7b
  jmp __alltraps
c0102d0f:	e9 8a fb ff ff       	jmp    c010289e <__alltraps>

c0102d14 <vector124>:
.globl vector124
vector124:
  pushl $0
c0102d14:	6a 00                	push   $0x0
  pushl $124
c0102d16:	6a 7c                	push   $0x7c
  jmp __alltraps
c0102d18:	e9 81 fb ff ff       	jmp    c010289e <__alltraps>

c0102d1d <vector125>:
.globl vector125
vector125:
  pushl $0
c0102d1d:	6a 00                	push   $0x0
  pushl $125
c0102d1f:	6a 7d                	push   $0x7d
  jmp __alltraps
c0102d21:	e9 78 fb ff ff       	jmp    c010289e <__alltraps>

c0102d26 <vector126>:
.globl vector126
vector126:
  pushl $0
c0102d26:	6a 00                	push   $0x0
  pushl $126
c0102d28:	6a 7e                	push   $0x7e
  jmp __alltraps
c0102d2a:	e9 6f fb ff ff       	jmp    c010289e <__alltraps>

c0102d2f <vector127>:
.globl vector127
vector127:
  pushl $0
c0102d2f:	6a 00                	push   $0x0
  pushl $127
c0102d31:	6a 7f                	push   $0x7f
  jmp __alltraps
c0102d33:	e9 66 fb ff ff       	jmp    c010289e <__alltraps>

c0102d38 <vector128>:
.globl vector128
vector128:
  pushl $0
c0102d38:	6a 00                	push   $0x0
  pushl $128
c0102d3a:	68 80 00 00 00       	push   $0x80
  jmp __alltraps
c0102d3f:	e9 5a fb ff ff       	jmp    c010289e <__alltraps>

c0102d44 <vector129>:
.globl vector129
vector129:
  pushl $0
c0102d44:	6a 00                	push   $0x0
  pushl $129
c0102d46:	68 81 00 00 00       	push   $0x81
  jmp __alltraps
c0102d4b:	e9 4e fb ff ff       	jmp    c010289e <__alltraps>

c0102d50 <vector130>:
.globl vector130
vector130:
  pushl $0
c0102d50:	6a 00                	push   $0x0
  pushl $130
c0102d52:	68 82 00 00 00       	push   $0x82
  jmp __alltraps
c0102d57:	e9 42 fb ff ff       	jmp    c010289e <__alltraps>

c0102d5c <vector131>:
.globl vector131
vector131:
  pushl $0
c0102d5c:	6a 00                	push   $0x0
  pushl $131
c0102d5e:	68 83 00 00 00       	push   $0x83
  jmp __alltraps
c0102d63:	e9 36 fb ff ff       	jmp    c010289e <__alltraps>

c0102d68 <vector132>:
.globl vector132
vector132:
  pushl $0
c0102d68:	6a 00                	push   $0x0
  pushl $132
c0102d6a:	68 84 00 00 00       	push   $0x84
  jmp __alltraps
c0102d6f:	e9 2a fb ff ff       	jmp    c010289e <__alltraps>

c0102d74 <vector133>:
.globl vector133
vector133:
  pushl $0
c0102d74:	6a 00                	push   $0x0
  pushl $133
c0102d76:	68 85 00 00 00       	push   $0x85
  jmp __alltraps
c0102d7b:	e9 1e fb ff ff       	jmp    c010289e <__alltraps>

c0102d80 <vector134>:
.globl vector134
vector134:
  pushl $0
c0102d80:	6a 00                	push   $0x0
  pushl $134
c0102d82:	68 86 00 00 00       	push   $0x86
  jmp __alltraps
c0102d87:	e9 12 fb ff ff       	jmp    c010289e <__alltraps>

c0102d8c <vector135>:
.globl vector135
vector135:
  pushl $0
c0102d8c:	6a 00                	push   $0x0
  pushl $135
c0102d8e:	68 87 00 00 00       	push   $0x87
  jmp __alltraps
c0102d93:	e9 06 fb ff ff       	jmp    c010289e <__alltraps>

c0102d98 <vector136>:
.globl vector136
vector136:
  pushl $0
c0102d98:	6a 00                	push   $0x0
  pushl $136
c0102d9a:	68 88 00 00 00       	push   $0x88
  jmp __alltraps
c0102d9f:	e9 fa fa ff ff       	jmp    c010289e <__alltraps>

c0102da4 <vector137>:
.globl vector137
vector137:
  pushl $0
c0102da4:	6a 00                	push   $0x0
  pushl $137
c0102da6:	68 89 00 00 00       	push   $0x89
  jmp __alltraps
c0102dab:	e9 ee fa ff ff       	jmp    c010289e <__alltraps>

c0102db0 <vector138>:
.globl vector138
vector138:
  pushl $0
c0102db0:	6a 00                	push   $0x0
  pushl $138
c0102db2:	68 8a 00 00 00       	push   $0x8a
  jmp __alltraps
c0102db7:	e9 e2 fa ff ff       	jmp    c010289e <__alltraps>

c0102dbc <vector139>:
.globl vector139
vector139:
  pushl $0
c0102dbc:	6a 00                	push   $0x0
  pushl $139
c0102dbe:	68 8b 00 00 00       	push   $0x8b
  jmp __alltraps
c0102dc3:	e9 d6 fa ff ff       	jmp    c010289e <__alltraps>

c0102dc8 <vector140>:
.globl vector140
vector140:
  pushl $0
c0102dc8:	6a 00                	push   $0x0
  pushl $140
c0102dca:	68 8c 00 00 00       	push   $0x8c
  jmp __alltraps
c0102dcf:	e9 ca fa ff ff       	jmp    c010289e <__alltraps>

c0102dd4 <vector141>:
.globl vector141
vector141:
  pushl $0
c0102dd4:	6a 00                	push   $0x0
  pushl $141
c0102dd6:	68 8d 00 00 00       	push   $0x8d
  jmp __alltraps
c0102ddb:	e9 be fa ff ff       	jmp    c010289e <__alltraps>

c0102de0 <vector142>:
.globl vector142
vector142:
  pushl $0
c0102de0:	6a 00                	push   $0x0
  pushl $142
c0102de2:	68 8e 00 00 00       	push   $0x8e
  jmp __alltraps
c0102de7:	e9 b2 fa ff ff       	jmp    c010289e <__alltraps>

c0102dec <vector143>:
.globl vector143
vector143:
  pushl $0
c0102dec:	6a 00                	push   $0x0
  pushl $143
c0102dee:	68 8f 00 00 00       	push   $0x8f
  jmp __alltraps
c0102df3:	e9 a6 fa ff ff       	jmp    c010289e <__alltraps>

c0102df8 <vector144>:
.globl vector144
vector144:
  pushl $0
c0102df8:	6a 00                	push   $0x0
  pushl $144
c0102dfa:	68 90 00 00 00       	push   $0x90
  jmp __alltraps
c0102dff:	e9 9a fa ff ff       	jmp    c010289e <__alltraps>

c0102e04 <vector145>:
.globl vector145
vector145:
  pushl $0
c0102e04:	6a 00                	push   $0x0
  pushl $145
c0102e06:	68 91 00 00 00       	push   $0x91
  jmp __alltraps
c0102e0b:	e9 8e fa ff ff       	jmp    c010289e <__alltraps>

c0102e10 <vector146>:
.globl vector146
vector146:
  pushl $0
c0102e10:	6a 00                	push   $0x0
  pushl $146
c0102e12:	68 92 00 00 00       	push   $0x92
  jmp __alltraps
c0102e17:	e9 82 fa ff ff       	jmp    c010289e <__alltraps>

c0102e1c <vector147>:
.globl vector147
vector147:
  pushl $0
c0102e1c:	6a 00                	push   $0x0
  pushl $147
c0102e1e:	68 93 00 00 00       	push   $0x93
  jmp __alltraps
c0102e23:	e9 76 fa ff ff       	jmp    c010289e <__alltraps>

c0102e28 <vector148>:
.globl vector148
vector148:
  pushl $0
c0102e28:	6a 00                	push   $0x0
  pushl $148
c0102e2a:	68 94 00 00 00       	push   $0x94
  jmp __alltraps
c0102e2f:	e9 6a fa ff ff       	jmp    c010289e <__alltraps>

c0102e34 <vector149>:
.globl vector149
vector149:
  pushl $0
c0102e34:	6a 00                	push   $0x0
  pushl $149
c0102e36:	68 95 00 00 00       	push   $0x95
  jmp __alltraps
c0102e3b:	e9 5e fa ff ff       	jmp    c010289e <__alltraps>

c0102e40 <vector150>:
.globl vector150
vector150:
  pushl $0
c0102e40:	6a 00                	push   $0x0
  pushl $150
c0102e42:	68 96 00 00 00       	push   $0x96
  jmp __alltraps
c0102e47:	e9 52 fa ff ff       	jmp    c010289e <__alltraps>

c0102e4c <vector151>:
.globl vector151
vector151:
  pushl $0
c0102e4c:	6a 00                	push   $0x0
  pushl $151
c0102e4e:	68 97 00 00 00       	push   $0x97
  jmp __alltraps
c0102e53:	e9 46 fa ff ff       	jmp    c010289e <__alltraps>

c0102e58 <vector152>:
.globl vector152
vector152:
  pushl $0
c0102e58:	6a 00                	push   $0x0
  pushl $152
c0102e5a:	68 98 00 00 00       	push   $0x98
  jmp __alltraps
c0102e5f:	e9 3a fa ff ff       	jmp    c010289e <__alltraps>

c0102e64 <vector153>:
.globl vector153
vector153:
  pushl $0
c0102e64:	6a 00                	push   $0x0
  pushl $153
c0102e66:	68 99 00 00 00       	push   $0x99
  jmp __alltraps
c0102e6b:	e9 2e fa ff ff       	jmp    c010289e <__alltraps>

c0102e70 <vector154>:
.globl vector154
vector154:
  pushl $0
c0102e70:	6a 00                	push   $0x0
  pushl $154
c0102e72:	68 9a 00 00 00       	push   $0x9a
  jmp __alltraps
c0102e77:	e9 22 fa ff ff       	jmp    c010289e <__alltraps>

c0102e7c <vector155>:
.globl vector155
vector155:
  pushl $0
c0102e7c:	6a 00                	push   $0x0
  pushl $155
c0102e7e:	68 9b 00 00 00       	push   $0x9b
  jmp __alltraps
c0102e83:	e9 16 fa ff ff       	jmp    c010289e <__alltraps>

c0102e88 <vector156>:
.globl vector156
vector156:
  pushl $0
c0102e88:	6a 00                	push   $0x0
  pushl $156
c0102e8a:	68 9c 00 00 00       	push   $0x9c
  jmp __alltraps
c0102e8f:	e9 0a fa ff ff       	jmp    c010289e <__alltraps>

c0102e94 <vector157>:
.globl vector157
vector157:
  pushl $0
c0102e94:	6a 00                	push   $0x0
  pushl $157
c0102e96:	68 9d 00 00 00       	push   $0x9d
  jmp __alltraps
c0102e9b:	e9 fe f9 ff ff       	jmp    c010289e <__alltraps>

c0102ea0 <vector158>:
.globl vector158
vector158:
  pushl $0
c0102ea0:	6a 00                	push   $0x0
  pushl $158
c0102ea2:	68 9e 00 00 00       	push   $0x9e
  jmp __alltraps
c0102ea7:	e9 f2 f9 ff ff       	jmp    c010289e <__alltraps>

c0102eac <vector159>:
.globl vector159
vector159:
  pushl $0
c0102eac:	6a 00                	push   $0x0
  pushl $159
c0102eae:	68 9f 00 00 00       	push   $0x9f
  jmp __alltraps
c0102eb3:	e9 e6 f9 ff ff       	jmp    c010289e <__alltraps>

c0102eb8 <vector160>:
.globl vector160
vector160:
  pushl $0
c0102eb8:	6a 00                	push   $0x0
  pushl $160
c0102eba:	68 a0 00 00 00       	push   $0xa0
  jmp __alltraps
c0102ebf:	e9 da f9 ff ff       	jmp    c010289e <__alltraps>

c0102ec4 <vector161>:
.globl vector161
vector161:
  pushl $0
c0102ec4:	6a 00                	push   $0x0
  pushl $161
c0102ec6:	68 a1 00 00 00       	push   $0xa1
  jmp __alltraps
c0102ecb:	e9 ce f9 ff ff       	jmp    c010289e <__alltraps>

c0102ed0 <vector162>:
.globl vector162
vector162:
  pushl $0
c0102ed0:	6a 00                	push   $0x0
  pushl $162
c0102ed2:	68 a2 00 00 00       	push   $0xa2
  jmp __alltraps
c0102ed7:	e9 c2 f9 ff ff       	jmp    c010289e <__alltraps>

c0102edc <vector163>:
.globl vector163
vector163:
  pushl $0
c0102edc:	6a 00                	push   $0x0
  pushl $163
c0102ede:	68 a3 00 00 00       	push   $0xa3
  jmp __alltraps
c0102ee3:	e9 b6 f9 ff ff       	jmp    c010289e <__alltraps>

c0102ee8 <vector164>:
.globl vector164
vector164:
  pushl $0
c0102ee8:	6a 00                	push   $0x0
  pushl $164
c0102eea:	68 a4 00 00 00       	push   $0xa4
  jmp __alltraps
c0102eef:	e9 aa f9 ff ff       	jmp    c010289e <__alltraps>

c0102ef4 <vector165>:
.globl vector165
vector165:
  pushl $0
c0102ef4:	6a 00                	push   $0x0
  pushl $165
c0102ef6:	68 a5 00 00 00       	push   $0xa5
  jmp __alltraps
c0102efb:	e9 9e f9 ff ff       	jmp    c010289e <__alltraps>

c0102f00 <vector166>:
.globl vector166
vector166:
  pushl $0
c0102f00:	6a 00                	push   $0x0
  pushl $166
c0102f02:	68 a6 00 00 00       	push   $0xa6
  jmp __alltraps
c0102f07:	e9 92 f9 ff ff       	jmp    c010289e <__alltraps>

c0102f0c <vector167>:
.globl vector167
vector167:
  pushl $0
c0102f0c:	6a 00                	push   $0x0
  pushl $167
c0102f0e:	68 a7 00 00 00       	push   $0xa7
  jmp __alltraps
c0102f13:	e9 86 f9 ff ff       	jmp    c010289e <__alltraps>

c0102f18 <vector168>:
.globl vector168
vector168:
  pushl $0
c0102f18:	6a 00                	push   $0x0
  pushl $168
c0102f1a:	68 a8 00 00 00       	push   $0xa8
  jmp __alltraps
c0102f1f:	e9 7a f9 ff ff       	jmp    c010289e <__alltraps>

c0102f24 <vector169>:
.globl vector169
vector169:
  pushl $0
c0102f24:	6a 00                	push   $0x0
  pushl $169
c0102f26:	68 a9 00 00 00       	push   $0xa9
  jmp __alltraps
c0102f2b:	e9 6e f9 ff ff       	jmp    c010289e <__alltraps>

c0102f30 <vector170>:
.globl vector170
vector170:
  pushl $0
c0102f30:	6a 00                	push   $0x0
  pushl $170
c0102f32:	68 aa 00 00 00       	push   $0xaa
  jmp __alltraps
c0102f37:	e9 62 f9 ff ff       	jmp    c010289e <__alltraps>

c0102f3c <vector171>:
.globl vector171
vector171:
  pushl $0
c0102f3c:	6a 00                	push   $0x0
  pushl $171
c0102f3e:	68 ab 00 00 00       	push   $0xab
  jmp __alltraps
c0102f43:	e9 56 f9 ff ff       	jmp    c010289e <__alltraps>

c0102f48 <vector172>:
.globl vector172
vector172:
  pushl $0
c0102f48:	6a 00                	push   $0x0
  pushl $172
c0102f4a:	68 ac 00 00 00       	push   $0xac
  jmp __alltraps
c0102f4f:	e9 4a f9 ff ff       	jmp    c010289e <__alltraps>

c0102f54 <vector173>:
.globl vector173
vector173:
  pushl $0
c0102f54:	6a 00                	push   $0x0
  pushl $173
c0102f56:	68 ad 00 00 00       	push   $0xad
  jmp __alltraps
c0102f5b:	e9 3e f9 ff ff       	jmp    c010289e <__alltraps>

c0102f60 <vector174>:
.globl vector174
vector174:
  pushl $0
c0102f60:	6a 00                	push   $0x0
  pushl $174
c0102f62:	68 ae 00 00 00       	push   $0xae
  jmp __alltraps
c0102f67:	e9 32 f9 ff ff       	jmp    c010289e <__alltraps>

c0102f6c <vector175>:
.globl vector175
vector175:
  pushl $0
c0102f6c:	6a 00                	push   $0x0
  pushl $175
c0102f6e:	68 af 00 00 00       	push   $0xaf
  jmp __alltraps
c0102f73:	e9 26 f9 ff ff       	jmp    c010289e <__alltraps>

c0102f78 <vector176>:
.globl vector176
vector176:
  pushl $0
c0102f78:	6a 00                	push   $0x0
  pushl $176
c0102f7a:	68 b0 00 00 00       	push   $0xb0
  jmp __alltraps
c0102f7f:	e9 1a f9 ff ff       	jmp    c010289e <__alltraps>

c0102f84 <vector177>:
.globl vector177
vector177:
  pushl $0
c0102f84:	6a 00                	push   $0x0
  pushl $177
c0102f86:	68 b1 00 00 00       	push   $0xb1
  jmp __alltraps
c0102f8b:	e9 0e f9 ff ff       	jmp    c010289e <__alltraps>

c0102f90 <vector178>:
.globl vector178
vector178:
  pushl $0
c0102f90:	6a 00                	push   $0x0
  pushl $178
c0102f92:	68 b2 00 00 00       	push   $0xb2
  jmp __alltraps
c0102f97:	e9 02 f9 ff ff       	jmp    c010289e <__alltraps>

c0102f9c <vector179>:
.globl vector179
vector179:
  pushl $0
c0102f9c:	6a 00                	push   $0x0
  pushl $179
c0102f9e:	68 b3 00 00 00       	push   $0xb3
  jmp __alltraps
c0102fa3:	e9 f6 f8 ff ff       	jmp    c010289e <__alltraps>

c0102fa8 <vector180>:
.globl vector180
vector180:
  pushl $0
c0102fa8:	6a 00                	push   $0x0
  pushl $180
c0102faa:	68 b4 00 00 00       	push   $0xb4
  jmp __alltraps
c0102faf:	e9 ea f8 ff ff       	jmp    c010289e <__alltraps>

c0102fb4 <vector181>:
.globl vector181
vector181:
  pushl $0
c0102fb4:	6a 00                	push   $0x0
  pushl $181
c0102fb6:	68 b5 00 00 00       	push   $0xb5
  jmp __alltraps
c0102fbb:	e9 de f8 ff ff       	jmp    c010289e <__alltraps>

c0102fc0 <vector182>:
.globl vector182
vector182:
  pushl $0
c0102fc0:	6a 00                	push   $0x0
  pushl $182
c0102fc2:	68 b6 00 00 00       	push   $0xb6
  jmp __alltraps
c0102fc7:	e9 d2 f8 ff ff       	jmp    c010289e <__alltraps>

c0102fcc <vector183>:
.globl vector183
vector183:
  pushl $0
c0102fcc:	6a 00                	push   $0x0
  pushl $183
c0102fce:	68 b7 00 00 00       	push   $0xb7
  jmp __alltraps
c0102fd3:	e9 c6 f8 ff ff       	jmp    c010289e <__alltraps>

c0102fd8 <vector184>:
.globl vector184
vector184:
  pushl $0
c0102fd8:	6a 00                	push   $0x0
  pushl $184
c0102fda:	68 b8 00 00 00       	push   $0xb8
  jmp __alltraps
c0102fdf:	e9 ba f8 ff ff       	jmp    c010289e <__alltraps>

c0102fe4 <vector185>:
.globl vector185
vector185:
  pushl $0
c0102fe4:	6a 00                	push   $0x0
  pushl $185
c0102fe6:	68 b9 00 00 00       	push   $0xb9
  jmp __alltraps
c0102feb:	e9 ae f8 ff ff       	jmp    c010289e <__alltraps>

c0102ff0 <vector186>:
.globl vector186
vector186:
  pushl $0
c0102ff0:	6a 00                	push   $0x0
  pushl $186
c0102ff2:	68 ba 00 00 00       	push   $0xba
  jmp __alltraps
c0102ff7:	e9 a2 f8 ff ff       	jmp    c010289e <__alltraps>

c0102ffc <vector187>:
.globl vector187
vector187:
  pushl $0
c0102ffc:	6a 00                	push   $0x0
  pushl $187
c0102ffe:	68 bb 00 00 00       	push   $0xbb
  jmp __alltraps
c0103003:	e9 96 f8 ff ff       	jmp    c010289e <__alltraps>

c0103008 <vector188>:
.globl vector188
vector188:
  pushl $0
c0103008:	6a 00                	push   $0x0
  pushl $188
c010300a:	68 bc 00 00 00       	push   $0xbc
  jmp __alltraps
c010300f:	e9 8a f8 ff ff       	jmp    c010289e <__alltraps>

c0103014 <vector189>:
.globl vector189
vector189:
  pushl $0
c0103014:	6a 00                	push   $0x0
  pushl $189
c0103016:	68 bd 00 00 00       	push   $0xbd
  jmp __alltraps
c010301b:	e9 7e f8 ff ff       	jmp    c010289e <__alltraps>

c0103020 <vector190>:
.globl vector190
vector190:
  pushl $0
c0103020:	6a 00                	push   $0x0
  pushl $190
c0103022:	68 be 00 00 00       	push   $0xbe
  jmp __alltraps
c0103027:	e9 72 f8 ff ff       	jmp    c010289e <__alltraps>

c010302c <vector191>:
.globl vector191
vector191:
  pushl $0
c010302c:	6a 00                	push   $0x0
  pushl $191
c010302e:	68 bf 00 00 00       	push   $0xbf
  jmp __alltraps
c0103033:	e9 66 f8 ff ff       	jmp    c010289e <__alltraps>

c0103038 <vector192>:
.globl vector192
vector192:
  pushl $0
c0103038:	6a 00                	push   $0x0
  pushl $192
c010303a:	68 c0 00 00 00       	push   $0xc0
  jmp __alltraps
c010303f:	e9 5a f8 ff ff       	jmp    c010289e <__alltraps>

c0103044 <vector193>:
.globl vector193
vector193:
  pushl $0
c0103044:	6a 00                	push   $0x0
  pushl $193
c0103046:	68 c1 00 00 00       	push   $0xc1
  jmp __alltraps
c010304b:	e9 4e f8 ff ff       	jmp    c010289e <__alltraps>

c0103050 <vector194>:
.globl vector194
vector194:
  pushl $0
c0103050:	6a 00                	push   $0x0
  pushl $194
c0103052:	68 c2 00 00 00       	push   $0xc2
  jmp __alltraps
c0103057:	e9 42 f8 ff ff       	jmp    c010289e <__alltraps>

c010305c <vector195>:
.globl vector195
vector195:
  pushl $0
c010305c:	6a 00                	push   $0x0
  pushl $195
c010305e:	68 c3 00 00 00       	push   $0xc3
  jmp __alltraps
c0103063:	e9 36 f8 ff ff       	jmp    c010289e <__alltraps>

c0103068 <vector196>:
.globl vector196
vector196:
  pushl $0
c0103068:	6a 00                	push   $0x0
  pushl $196
c010306a:	68 c4 00 00 00       	push   $0xc4
  jmp __alltraps
c010306f:	e9 2a f8 ff ff       	jmp    c010289e <__alltraps>

c0103074 <vector197>:
.globl vector197
vector197:
  pushl $0
c0103074:	6a 00                	push   $0x0
  pushl $197
c0103076:	68 c5 00 00 00       	push   $0xc5
  jmp __alltraps
c010307b:	e9 1e f8 ff ff       	jmp    c010289e <__alltraps>

c0103080 <vector198>:
.globl vector198
vector198:
  pushl $0
c0103080:	6a 00                	push   $0x0
  pushl $198
c0103082:	68 c6 00 00 00       	push   $0xc6
  jmp __alltraps
c0103087:	e9 12 f8 ff ff       	jmp    c010289e <__alltraps>

c010308c <vector199>:
.globl vector199
vector199:
  pushl $0
c010308c:	6a 00                	push   $0x0
  pushl $199
c010308e:	68 c7 00 00 00       	push   $0xc7
  jmp __alltraps
c0103093:	e9 06 f8 ff ff       	jmp    c010289e <__alltraps>

c0103098 <vector200>:
.globl vector200
vector200:
  pushl $0
c0103098:	6a 00                	push   $0x0
  pushl $200
c010309a:	68 c8 00 00 00       	push   $0xc8
  jmp __alltraps
c010309f:	e9 fa f7 ff ff       	jmp    c010289e <__alltraps>

c01030a4 <vector201>:
.globl vector201
vector201:
  pushl $0
c01030a4:	6a 00                	push   $0x0
  pushl $201
c01030a6:	68 c9 00 00 00       	push   $0xc9
  jmp __alltraps
c01030ab:	e9 ee f7 ff ff       	jmp    c010289e <__alltraps>

c01030b0 <vector202>:
.globl vector202
vector202:
  pushl $0
c01030b0:	6a 00                	push   $0x0
  pushl $202
c01030b2:	68 ca 00 00 00       	push   $0xca
  jmp __alltraps
c01030b7:	e9 e2 f7 ff ff       	jmp    c010289e <__alltraps>

c01030bc <vector203>:
.globl vector203
vector203:
  pushl $0
c01030bc:	6a 00                	push   $0x0
  pushl $203
c01030be:	68 cb 00 00 00       	push   $0xcb
  jmp __alltraps
c01030c3:	e9 d6 f7 ff ff       	jmp    c010289e <__alltraps>

c01030c8 <vector204>:
.globl vector204
vector204:
  pushl $0
c01030c8:	6a 00                	push   $0x0
  pushl $204
c01030ca:	68 cc 00 00 00       	push   $0xcc
  jmp __alltraps
c01030cf:	e9 ca f7 ff ff       	jmp    c010289e <__alltraps>

c01030d4 <vector205>:
.globl vector205
vector205:
  pushl $0
c01030d4:	6a 00                	push   $0x0
  pushl $205
c01030d6:	68 cd 00 00 00       	push   $0xcd
  jmp __alltraps
c01030db:	e9 be f7 ff ff       	jmp    c010289e <__alltraps>

c01030e0 <vector206>:
.globl vector206
vector206:
  pushl $0
c01030e0:	6a 00                	push   $0x0
  pushl $206
c01030e2:	68 ce 00 00 00       	push   $0xce
  jmp __alltraps
c01030e7:	e9 b2 f7 ff ff       	jmp    c010289e <__alltraps>

c01030ec <vector207>:
.globl vector207
vector207:
  pushl $0
c01030ec:	6a 00                	push   $0x0
  pushl $207
c01030ee:	68 cf 00 00 00       	push   $0xcf
  jmp __alltraps
c01030f3:	e9 a6 f7 ff ff       	jmp    c010289e <__alltraps>

c01030f8 <vector208>:
.globl vector208
vector208:
  pushl $0
c01030f8:	6a 00                	push   $0x0
  pushl $208
c01030fa:	68 d0 00 00 00       	push   $0xd0
  jmp __alltraps
c01030ff:	e9 9a f7 ff ff       	jmp    c010289e <__alltraps>

c0103104 <vector209>:
.globl vector209
vector209:
  pushl $0
c0103104:	6a 00                	push   $0x0
  pushl $209
c0103106:	68 d1 00 00 00       	push   $0xd1
  jmp __alltraps
c010310b:	e9 8e f7 ff ff       	jmp    c010289e <__alltraps>

c0103110 <vector210>:
.globl vector210
vector210:
  pushl $0
c0103110:	6a 00                	push   $0x0
  pushl $210
c0103112:	68 d2 00 00 00       	push   $0xd2
  jmp __alltraps
c0103117:	e9 82 f7 ff ff       	jmp    c010289e <__alltraps>

c010311c <vector211>:
.globl vector211
vector211:
  pushl $0
c010311c:	6a 00                	push   $0x0
  pushl $211
c010311e:	68 d3 00 00 00       	push   $0xd3
  jmp __alltraps
c0103123:	e9 76 f7 ff ff       	jmp    c010289e <__alltraps>

c0103128 <vector212>:
.globl vector212
vector212:
  pushl $0
c0103128:	6a 00                	push   $0x0
  pushl $212
c010312a:	68 d4 00 00 00       	push   $0xd4
  jmp __alltraps
c010312f:	e9 6a f7 ff ff       	jmp    c010289e <__alltraps>

c0103134 <vector213>:
.globl vector213
vector213:
  pushl $0
c0103134:	6a 00                	push   $0x0
  pushl $213
c0103136:	68 d5 00 00 00       	push   $0xd5
  jmp __alltraps
c010313b:	e9 5e f7 ff ff       	jmp    c010289e <__alltraps>

c0103140 <vector214>:
.globl vector214
vector214:
  pushl $0
c0103140:	6a 00                	push   $0x0
  pushl $214
c0103142:	68 d6 00 00 00       	push   $0xd6
  jmp __alltraps
c0103147:	e9 52 f7 ff ff       	jmp    c010289e <__alltraps>

c010314c <vector215>:
.globl vector215
vector215:
  pushl $0
c010314c:	6a 00                	push   $0x0
  pushl $215
c010314e:	68 d7 00 00 00       	push   $0xd7
  jmp __alltraps
c0103153:	e9 46 f7 ff ff       	jmp    c010289e <__alltraps>

c0103158 <vector216>:
.globl vector216
vector216:
  pushl $0
c0103158:	6a 00                	push   $0x0
  pushl $216
c010315a:	68 d8 00 00 00       	push   $0xd8
  jmp __alltraps
c010315f:	e9 3a f7 ff ff       	jmp    c010289e <__alltraps>

c0103164 <vector217>:
.globl vector217
vector217:
  pushl $0
c0103164:	6a 00                	push   $0x0
  pushl $217
c0103166:	68 d9 00 00 00       	push   $0xd9
  jmp __alltraps
c010316b:	e9 2e f7 ff ff       	jmp    c010289e <__alltraps>

c0103170 <vector218>:
.globl vector218
vector218:
  pushl $0
c0103170:	6a 00                	push   $0x0
  pushl $218
c0103172:	68 da 00 00 00       	push   $0xda
  jmp __alltraps
c0103177:	e9 22 f7 ff ff       	jmp    c010289e <__alltraps>

c010317c <vector219>:
.globl vector219
vector219:
  pushl $0
c010317c:	6a 00                	push   $0x0
  pushl $219
c010317e:	68 db 00 00 00       	push   $0xdb
  jmp __alltraps
c0103183:	e9 16 f7 ff ff       	jmp    c010289e <__alltraps>

c0103188 <vector220>:
.globl vector220
vector220:
  pushl $0
c0103188:	6a 00                	push   $0x0
  pushl $220
c010318a:	68 dc 00 00 00       	push   $0xdc
  jmp __alltraps
c010318f:	e9 0a f7 ff ff       	jmp    c010289e <__alltraps>

c0103194 <vector221>:
.globl vector221
vector221:
  pushl $0
c0103194:	6a 00                	push   $0x0
  pushl $221
c0103196:	68 dd 00 00 00       	push   $0xdd
  jmp __alltraps
c010319b:	e9 fe f6 ff ff       	jmp    c010289e <__alltraps>

c01031a0 <vector222>:
.globl vector222
vector222:
  pushl $0
c01031a0:	6a 00                	push   $0x0
  pushl $222
c01031a2:	68 de 00 00 00       	push   $0xde
  jmp __alltraps
c01031a7:	e9 f2 f6 ff ff       	jmp    c010289e <__alltraps>

c01031ac <vector223>:
.globl vector223
vector223:
  pushl $0
c01031ac:	6a 00                	push   $0x0
  pushl $223
c01031ae:	68 df 00 00 00       	push   $0xdf
  jmp __alltraps
c01031b3:	e9 e6 f6 ff ff       	jmp    c010289e <__alltraps>

c01031b8 <vector224>:
.globl vector224
vector224:
  pushl $0
c01031b8:	6a 00                	push   $0x0
  pushl $224
c01031ba:	68 e0 00 00 00       	push   $0xe0
  jmp __alltraps
c01031bf:	e9 da f6 ff ff       	jmp    c010289e <__alltraps>

c01031c4 <vector225>:
.globl vector225
vector225:
  pushl $0
c01031c4:	6a 00                	push   $0x0
  pushl $225
c01031c6:	68 e1 00 00 00       	push   $0xe1
  jmp __alltraps
c01031cb:	e9 ce f6 ff ff       	jmp    c010289e <__alltraps>

c01031d0 <vector226>:
.globl vector226
vector226:
  pushl $0
c01031d0:	6a 00                	push   $0x0
  pushl $226
c01031d2:	68 e2 00 00 00       	push   $0xe2
  jmp __alltraps
c01031d7:	e9 c2 f6 ff ff       	jmp    c010289e <__alltraps>

c01031dc <vector227>:
.globl vector227
vector227:
  pushl $0
c01031dc:	6a 00                	push   $0x0
  pushl $227
c01031de:	68 e3 00 00 00       	push   $0xe3
  jmp __alltraps
c01031e3:	e9 b6 f6 ff ff       	jmp    c010289e <__alltraps>

c01031e8 <vector228>:
.globl vector228
vector228:
  pushl $0
c01031e8:	6a 00                	push   $0x0
  pushl $228
c01031ea:	68 e4 00 00 00       	push   $0xe4
  jmp __alltraps
c01031ef:	e9 aa f6 ff ff       	jmp    c010289e <__alltraps>

c01031f4 <vector229>:
.globl vector229
vector229:
  pushl $0
c01031f4:	6a 00                	push   $0x0
  pushl $229
c01031f6:	68 e5 00 00 00       	push   $0xe5
  jmp __alltraps
c01031fb:	e9 9e f6 ff ff       	jmp    c010289e <__alltraps>

c0103200 <vector230>:
.globl vector230
vector230:
  pushl $0
c0103200:	6a 00                	push   $0x0
  pushl $230
c0103202:	68 e6 00 00 00       	push   $0xe6
  jmp __alltraps
c0103207:	e9 92 f6 ff ff       	jmp    c010289e <__alltraps>

c010320c <vector231>:
.globl vector231
vector231:
  pushl $0
c010320c:	6a 00                	push   $0x0
  pushl $231
c010320e:	68 e7 00 00 00       	push   $0xe7
  jmp __alltraps
c0103213:	e9 86 f6 ff ff       	jmp    c010289e <__alltraps>

c0103218 <vector232>:
.globl vector232
vector232:
  pushl $0
c0103218:	6a 00                	push   $0x0
  pushl $232
c010321a:	68 e8 00 00 00       	push   $0xe8
  jmp __alltraps
c010321f:	e9 7a f6 ff ff       	jmp    c010289e <__alltraps>

c0103224 <vector233>:
.globl vector233
vector233:
  pushl $0
c0103224:	6a 00                	push   $0x0
  pushl $233
c0103226:	68 e9 00 00 00       	push   $0xe9
  jmp __alltraps
c010322b:	e9 6e f6 ff ff       	jmp    c010289e <__alltraps>

c0103230 <vector234>:
.globl vector234
vector234:
  pushl $0
c0103230:	6a 00                	push   $0x0
  pushl $234
c0103232:	68 ea 00 00 00       	push   $0xea
  jmp __alltraps
c0103237:	e9 62 f6 ff ff       	jmp    c010289e <__alltraps>

c010323c <vector235>:
.globl vector235
vector235:
  pushl $0
c010323c:	6a 00                	push   $0x0
  pushl $235
c010323e:	68 eb 00 00 00       	push   $0xeb
  jmp __alltraps
c0103243:	e9 56 f6 ff ff       	jmp    c010289e <__alltraps>

c0103248 <vector236>:
.globl vector236
vector236:
  pushl $0
c0103248:	6a 00                	push   $0x0
  pushl $236
c010324a:	68 ec 00 00 00       	push   $0xec
  jmp __alltraps
c010324f:	e9 4a f6 ff ff       	jmp    c010289e <__alltraps>

c0103254 <vector237>:
.globl vector237
vector237:
  pushl $0
c0103254:	6a 00                	push   $0x0
  pushl $237
c0103256:	68 ed 00 00 00       	push   $0xed
  jmp __alltraps
c010325b:	e9 3e f6 ff ff       	jmp    c010289e <__alltraps>

c0103260 <vector238>:
.globl vector238
vector238:
  pushl $0
c0103260:	6a 00                	push   $0x0
  pushl $238
c0103262:	68 ee 00 00 00       	push   $0xee
  jmp __alltraps
c0103267:	e9 32 f6 ff ff       	jmp    c010289e <__alltraps>

c010326c <vector239>:
.globl vector239
vector239:
  pushl $0
c010326c:	6a 00                	push   $0x0
  pushl $239
c010326e:	68 ef 00 00 00       	push   $0xef
  jmp __alltraps
c0103273:	e9 26 f6 ff ff       	jmp    c010289e <__alltraps>

c0103278 <vector240>:
.globl vector240
vector240:
  pushl $0
c0103278:	6a 00                	push   $0x0
  pushl $240
c010327a:	68 f0 00 00 00       	push   $0xf0
  jmp __alltraps
c010327f:	e9 1a f6 ff ff       	jmp    c010289e <__alltraps>

c0103284 <vector241>:
.globl vector241
vector241:
  pushl $0
c0103284:	6a 00                	push   $0x0
  pushl $241
c0103286:	68 f1 00 00 00       	push   $0xf1
  jmp __alltraps
c010328b:	e9 0e f6 ff ff       	jmp    c010289e <__alltraps>

c0103290 <vector242>:
.globl vector242
vector242:
  pushl $0
c0103290:	6a 00                	push   $0x0
  pushl $242
c0103292:	68 f2 00 00 00       	push   $0xf2
  jmp __alltraps
c0103297:	e9 02 f6 ff ff       	jmp    c010289e <__alltraps>

c010329c <vector243>:
.globl vector243
vector243:
  pushl $0
c010329c:	6a 00                	push   $0x0
  pushl $243
c010329e:	68 f3 00 00 00       	push   $0xf3
  jmp __alltraps
c01032a3:	e9 f6 f5 ff ff       	jmp    c010289e <__alltraps>

c01032a8 <vector244>:
.globl vector244
vector244:
  pushl $0
c01032a8:	6a 00                	push   $0x0
  pushl $244
c01032aa:	68 f4 00 00 00       	push   $0xf4
  jmp __alltraps
c01032af:	e9 ea f5 ff ff       	jmp    c010289e <__alltraps>

c01032b4 <vector245>:
.globl vector245
vector245:
  pushl $0
c01032b4:	6a 00                	push   $0x0
  pushl $245
c01032b6:	68 f5 00 00 00       	push   $0xf5
  jmp __alltraps
c01032bb:	e9 de f5 ff ff       	jmp    c010289e <__alltraps>

c01032c0 <vector246>:
.globl vector246
vector246:
  pushl $0
c01032c0:	6a 00                	push   $0x0
  pushl $246
c01032c2:	68 f6 00 00 00       	push   $0xf6
  jmp __alltraps
c01032c7:	e9 d2 f5 ff ff       	jmp    c010289e <__alltraps>

c01032cc <vector247>:
.globl vector247
vector247:
  pushl $0
c01032cc:	6a 00                	push   $0x0
  pushl $247
c01032ce:	68 f7 00 00 00       	push   $0xf7
  jmp __alltraps
c01032d3:	e9 c6 f5 ff ff       	jmp    c010289e <__alltraps>

c01032d8 <vector248>:
.globl vector248
vector248:
  pushl $0
c01032d8:	6a 00                	push   $0x0
  pushl $248
c01032da:	68 f8 00 00 00       	push   $0xf8
  jmp __alltraps
c01032df:	e9 ba f5 ff ff       	jmp    c010289e <__alltraps>

c01032e4 <vector249>:
.globl vector249
vector249:
  pushl $0
c01032e4:	6a 00                	push   $0x0
  pushl $249
c01032e6:	68 f9 00 00 00       	push   $0xf9
  jmp __alltraps
c01032eb:	e9 ae f5 ff ff       	jmp    c010289e <__alltraps>

c01032f0 <vector250>:
.globl vector250
vector250:
  pushl $0
c01032f0:	6a 00                	push   $0x0
  pushl $250
c01032f2:	68 fa 00 00 00       	push   $0xfa
  jmp __alltraps
c01032f7:	e9 a2 f5 ff ff       	jmp    c010289e <__alltraps>

c01032fc <vector251>:
.globl vector251
vector251:
  pushl $0
c01032fc:	6a 00                	push   $0x0
  pushl $251
c01032fe:	68 fb 00 00 00       	push   $0xfb
  jmp __alltraps
c0103303:	e9 96 f5 ff ff       	jmp    c010289e <__alltraps>

c0103308 <vector252>:
.globl vector252
vector252:
  pushl $0
c0103308:	6a 00                	push   $0x0
  pushl $252
c010330a:	68 fc 00 00 00       	push   $0xfc
  jmp __alltraps
c010330f:	e9 8a f5 ff ff       	jmp    c010289e <__alltraps>

c0103314 <vector253>:
.globl vector253
vector253:
  pushl $0
c0103314:	6a 00                	push   $0x0
  pushl $253
c0103316:	68 fd 00 00 00       	push   $0xfd
  jmp __alltraps
c010331b:	e9 7e f5 ff ff       	jmp    c010289e <__alltraps>

c0103320 <vector254>:
.globl vector254
vector254:
  pushl $0
c0103320:	6a 00                	push   $0x0
  pushl $254
c0103322:	68 fe 00 00 00       	push   $0xfe
  jmp __alltraps
c0103327:	e9 72 f5 ff ff       	jmp    c010289e <__alltraps>

c010332c <vector255>:
.globl vector255
vector255:
  pushl $0
c010332c:	6a 00                	push   $0x0
  pushl $255
c010332e:	68 ff 00 00 00       	push   $0xff
  jmp __alltraps
c0103333:	e9 66 f5 ff ff       	jmp    c010289e <__alltraps>

c0103338 <page2ppn>:

extern struct Page *pages;
extern size_t npage;

static inline ppn_t
page2ppn(struct Page *page) {
c0103338:	55                   	push   %ebp
c0103339:	89 e5                	mov    %esp,%ebp
    return page - pages;
c010333b:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c0103341:	8b 45 08             	mov    0x8(%ebp),%eax
c0103344:	29 d0                	sub    %edx,%eax
c0103346:	c1 f8 05             	sar    $0x5,%eax
}
c0103349:	5d                   	pop    %ebp
c010334a:	c3                   	ret    

c010334b <page2pa>:

static inline uintptr_t
page2pa(struct Page *page) {
c010334b:	55                   	push   %ebp
c010334c:	89 e5                	mov    %esp,%ebp
c010334e:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c0103351:	8b 45 08             	mov    0x8(%ebp),%eax
c0103354:	89 04 24             	mov    %eax,(%esp)
c0103357:	e8 dc ff ff ff       	call   c0103338 <page2ppn>
c010335c:	c1 e0 0c             	shl    $0xc,%eax
}
c010335f:	89 ec                	mov    %ebp,%esp
c0103361:	5d                   	pop    %ebp
c0103362:	c3                   	ret    

c0103363 <page_ref>:
pde2page(pde_t pde) {
    return pa2page(PDE_ADDR(pde));
}

static inline int
page_ref(struct Page *page) {
c0103363:	55                   	push   %ebp
c0103364:	89 e5                	mov    %esp,%ebp
    return page->ref;
c0103366:	8b 45 08             	mov    0x8(%ebp),%eax
c0103369:	8b 00                	mov    (%eax),%eax
}
c010336b:	5d                   	pop    %ebp
c010336c:	c3                   	ret    

c010336d <set_page_ref>:

static inline void
set_page_ref(struct Page *page, int val) {
c010336d:	55                   	push   %ebp
c010336e:	89 e5                	mov    %esp,%ebp
    page->ref = val;
c0103370:	8b 45 08             	mov    0x8(%ebp),%eax
c0103373:	8b 55 0c             	mov    0xc(%ebp),%edx
c0103376:	89 10                	mov    %edx,(%eax)
}
c0103378:	90                   	nop
c0103379:	5d                   	pop    %ebp
c010337a:	c3                   	ret    

c010337b <default_init>:
#define nr_free (free_area.nr_free)

//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。
//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。
static void
default_init(void) {
c010337b:	55                   	push   %ebp
c010337c:	89 e5                	mov    %esp,%ebp
c010337e:	83 ec 10             	sub    $0x10,%esp
c0103381:	c7 45 fc e4 bf 12 c0 	movl   $0xc012bfe4,-0x4(%ebp)
 * list_init - initialize a new entry
 * @elm:        new entry to be initialized
 * */
static inline void
list_init(list_entry_t *elm) {
    elm->prev = elm->next = elm;
c0103388:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010338b:	8b 55 fc             	mov    -0x4(%ebp),%edx
c010338e:	89 50 04             	mov    %edx,0x4(%eax)
c0103391:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0103394:	8b 50 04             	mov    0x4(%eax),%edx
c0103397:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010339a:	89 10                	mov    %edx,(%eax)
}
c010339c:	90                   	nop
    list_init(&free_list);
    nr_free = 0;
c010339d:	c7 05 ec bf 12 c0 00 	movl   $0x0,0xc012bfec
c01033a4:	00 00 00 
}
c01033a7:	90                   	nop
c01033a8:	89 ec                	mov    %ebp,%esp
c01033aa:	5d                   	pop    %ebp
c01033ab:	c3                   	ret    

c01033ac <default_init_memmap>:

//用于初始化一段连续的物理页，并将它们加入到空闲内存管理系统中.
//struct Page *base：指向要初始化的页块的起始地址。size_t n：要初始化的页的数量。
static void
default_init_memmap(struct Page *base, size_t n) {
c01033ac:	55                   	push   %ebp
c01033ad:	89 e5                	mov    %esp,%ebp
c01033af:	83 ec 48             	sub    $0x48,%esp
    assert(n > 0);// 确保请求的页数大于零
c01033b2:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c01033b6:	75 24                	jne    c01033dc <default_init_memmap+0x30>
c01033b8:	c7 44 24 0c 70 a9 10 	movl   $0xc010a970,0xc(%esp)
c01033bf:	c0 
c01033c0:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c01033c7:	c0 
c01033c8:	c7 44 24 04 9a 00 00 	movl   $0x9a,0x4(%esp)
c01033cf:	00 
c01033d0:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c01033d7:	e8 69 d8 ff ff       	call   c0100c45 <__panic>
    struct Page *p = base;// 指向当前初始化的页
c01033dc:	8b 45 08             	mov    0x8(%ebp),%eax
c01033df:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 遍历每一页，设置其状态
    for (; p != base + n; p ++) {
c01033e2:	eb 7d                	jmp    c0103461 <default_init_memmap+0xb5>
        assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留，函数将抛出错误。
c01033e4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01033e7:	83 c0 04             	add    $0x4,%eax
c01033ea:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
c01033f1:	89 45 ec             	mov    %eax,-0x14(%ebp)
 * @addr:   the address to count from
 * */
static inline bool
test_bit(int nr, volatile void *addr) {
    int oldbit;
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c01033f4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01033f7:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01033fa:	0f a3 10             	bt     %edx,(%eax)
c01033fd:	19 c0                	sbb    %eax,%eax
c01033ff:	89 45 e8             	mov    %eax,-0x18(%ebp)
    return oldbit != 0;
c0103402:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0103406:	0f 95 c0             	setne  %al
c0103409:	0f b6 c0             	movzbl %al,%eax
c010340c:	85 c0                	test   %eax,%eax
c010340e:	75 24                	jne    c0103434 <default_init_memmap+0x88>
c0103410:	c7 44 24 0c a1 a9 10 	movl   $0xc010a9a1,0xc(%esp)
c0103417:	c0 
c0103418:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c010341f:	c0 
c0103420:	c7 44 24 04 9e 00 00 	movl   $0x9e,0x4(%esp)
c0103427:	00 
c0103428:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c010342f:	e8 11 d8 ff ff       	call   c0100c45 <__panic>
        p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0，表示该页未分配、未使用。
c0103434:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103437:	c7 40 08 00 00 00 00 	movl   $0x0,0x8(%eax)
c010343e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103441:	8b 50 08             	mov    0x8(%eax),%edx
c0103444:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103447:	89 50 04             	mov    %edx,0x4(%eax)
        set_page_ref(p, 0);//将页的引用计数设置为 0，表明没有任何引用指向此页。
c010344a:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0103451:	00 
c0103452:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103455:	89 04 24             	mov    %eax,(%esp)
c0103458:	e8 10 ff ff ff       	call   c010336d <set_page_ref>
    for (; p != base + n; p ++) {
c010345d:	83 45 f4 20          	addl   $0x20,-0xc(%ebp)
c0103461:	8b 45 0c             	mov    0xc(%ebp),%eax
c0103464:	c1 e0 05             	shl    $0x5,%eax
c0103467:	89 c2                	mov    %eax,%edx
c0103469:	8b 45 08             	mov    0x8(%ebp),%eax
c010346c:	01 d0                	add    %edx,%eax
c010346e:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0103471:	0f 85 6d ff ff ff    	jne    c01033e4 <default_init_memmap+0x38>
    }
    // 设置第一个页的 property 为块的总数
    base->property = n;
c0103477:	8b 45 08             	mov    0x8(%ebp),%eax
c010347a:	8b 55 0c             	mov    0xc(%ebp),%edx
c010347d:	89 50 08             	mov    %edx,0x8(%eax)
    SetPageProperty(base);// 设置当前页的有效标志
c0103480:	8b 45 08             	mov    0x8(%ebp),%eax
c0103483:	83 c0 04             	add    $0x4,%eax
c0103486:	c7 45 d0 01 00 00 00 	movl   $0x1,-0x30(%ebp)
c010348d:	89 45 cc             	mov    %eax,-0x34(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0103490:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0103493:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0103496:	0f ab 10             	bts    %edx,(%eax)
}
c0103499:	90                   	nop
    nr_free += n;// 更新空闲页计数
c010349a:	8b 15 ec bf 12 c0    	mov    0xc012bfec,%edx
c01034a0:	8b 45 0c             	mov    0xc(%ebp),%eax
c01034a3:	01 d0                	add    %edx,%eax
c01034a5:	a3 ec bf 12 c0       	mov    %eax,0xc012bfec
    list_add_before(&free_list, &(base->page_link));// 将该块添加到空闲列表中
c01034aa:	8b 45 08             	mov    0x8(%ebp),%eax
c01034ad:	83 c0 0c             	add    $0xc,%eax
c01034b0:	c7 45 e4 e4 bf 12 c0 	movl   $0xc012bfe4,-0x1c(%ebp)
c01034b7:	89 45 e0             	mov    %eax,-0x20(%ebp)
 * Insert the new element @elm *before* the element @listelm which
 * is already in the list.
 * */
static inline void
list_add_before(list_entry_t *listelm, list_entry_t *elm) {
    __list_add(elm, listelm->prev, listelm);
c01034ba:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01034bd:	8b 00                	mov    (%eax),%eax
c01034bf:	8b 55 e0             	mov    -0x20(%ebp),%edx
c01034c2:	89 55 dc             	mov    %edx,-0x24(%ebp)
c01034c5:	89 45 d8             	mov    %eax,-0x28(%ebp)
c01034c8:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01034cb:	89 45 d4             	mov    %eax,-0x2c(%ebp)
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 * */
static inline void
__list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) {
    prev->next = next->prev = elm;
c01034ce:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01034d1:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01034d4:	89 10                	mov    %edx,(%eax)
c01034d6:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01034d9:	8b 10                	mov    (%eax),%edx
c01034db:	8b 45 d8             	mov    -0x28(%ebp),%eax
c01034de:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c01034e1:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01034e4:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01034e7:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c01034ea:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01034ed:	8b 55 d8             	mov    -0x28(%ebp),%edx
c01034f0:	89 10                	mov    %edx,(%eax)
}
c01034f2:	90                   	nop
}
c01034f3:	90                   	nop
}
c01034f4:	90                   	nop
c01034f5:	89 ec                	mov    %ebp,%esp
c01034f7:	5d                   	pop    %ebp
c01034f8:	c3                   	ret    

c01034f9 <default_alloc_pages>:

//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。
static struct Page *
default_alloc_pages(size_t n) {
c01034f9:	55                   	push   %ebp
c01034fa:	89 e5                	mov    %esp,%ebp
c01034fc:	83 ec 68             	sub    $0x68,%esp
    assert(n > 0);// 确保请求的页数大于零
c01034ff:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0103503:	75 24                	jne    c0103529 <default_alloc_pages+0x30>
c0103505:	c7 44 24 0c 70 a9 10 	movl   $0xc010a970,0xc(%esp)
c010350c:	c0 
c010350d:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103514:	c0 
c0103515:	c7 44 24 04 ac 00 00 	movl   $0xac,0x4(%esp)
c010351c:	00 
c010351d:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103524:	e8 1c d7 ff ff       	call   c0100c45 <__panic>
    if (n > nr_free) {// 检查请求的页数是否超过空闲页数
c0103529:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
c010352e:	39 45 08             	cmp    %eax,0x8(%ebp)
c0103531:	76 0a                	jbe    c010353d <default_alloc_pages+0x44>
        return NULL;
c0103533:	b8 00 00 00 00       	mov    $0x0,%eax
c0103538:	e9 3c 01 00 00       	jmp    c0103679 <default_alloc_pages+0x180>
    }
    struct Page *page = NULL;// 初始化分配的页指针
c010353d:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    list_entry_t *le = &free_list;// 初始化链表迭代器
c0103544:	c7 45 f0 e4 bf 12 c0 	movl   $0xc012bfe4,-0x10(%ebp)
    // 遍历空闲列表，寻找第一个满足条件的块
    while ((le = list_next(le)) != &free_list) {
c010354b:	eb 1c                	jmp    c0103569 <default_alloc_pages+0x70>
        struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体
c010354d:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103550:	83 e8 0c             	sub    $0xc,%eax
c0103553:	89 45 ec             	mov    %eax,-0x14(%ebp)
        if (p->property >= n) {// 检查当前块的页数是否满足请求
c0103556:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103559:	8b 40 08             	mov    0x8(%eax),%eax
c010355c:	39 45 08             	cmp    %eax,0x8(%ebp)
c010355f:	77 08                	ja     c0103569 <default_alloc_pages+0x70>
            page = p;// 找到合适的块
c0103561:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103564:	89 45 f4             	mov    %eax,-0xc(%ebp)
            break;// 退出循环
c0103567:	eb 18                	jmp    c0103581 <default_alloc_pages+0x88>
c0103569:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010356c:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    return listelm->next;
c010356f:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0103572:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != &free_list) {
c0103575:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0103578:	81 7d f0 e4 bf 12 c0 	cmpl   $0xc012bfe4,-0x10(%ebp)
c010357f:	75 cc                	jne    c010354d <default_alloc_pages+0x54>
        }
    }
    if (page != NULL) {// 如果找到合适的块
c0103581:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0103585:	0f 84 eb 00 00 00    	je     c0103676 <default_alloc_pages+0x17d>
        //list_del(&(page->page_link));// 从空闲列表中删除该块
        if (page->property > n) {
c010358b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010358e:	8b 40 08             	mov    0x8(%eax),%eax
c0103591:	39 45 08             	cmp    %eax,0x8(%ebp)
c0103594:	0f 83 88 00 00 00    	jae    c0103622 <default_alloc_pages+0x129>
            struct Page *p = page + n;// 指向剩余的页
c010359a:	8b 45 08             	mov    0x8(%ebp),%eax
c010359d:	c1 e0 05             	shl    $0x5,%eax
c01035a0:	89 c2                	mov    %eax,%edx
c01035a2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01035a5:	01 d0                	add    %edx,%eax
c01035a7:	89 45 e8             	mov    %eax,-0x18(%ebp)
            p->property = page->property - n;// 更新剩余块的页数
c01035aa:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01035ad:	8b 40 08             	mov    0x8(%eax),%eax
c01035b0:	2b 45 08             	sub    0x8(%ebp),%eax
c01035b3:	89 c2                	mov    %eax,%edx
c01035b5:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01035b8:	89 50 08             	mov    %edx,0x8(%eax)
            SetPageProperty(p);
c01035bb:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01035be:	83 c0 04             	add    $0x4,%eax
c01035c1:	c7 45 cc 01 00 00 00 	movl   $0x1,-0x34(%ebp)
c01035c8:	89 45 c8             	mov    %eax,-0x38(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c01035cb:	8b 45 c8             	mov    -0x38(%ebp),%eax
c01035ce:	8b 55 cc             	mov    -0x34(%ebp),%edx
c01035d1:	0f ab 10             	bts    %edx,(%eax)
}
c01035d4:	90                   	nop
            list_add_after(&(page->page_link), &(p->page_link));// 将剩余块添加回空闲列表
c01035d5:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01035d8:	83 c0 0c             	add    $0xc,%eax
c01035db:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01035de:	83 c2 0c             	add    $0xc,%edx
c01035e1:	89 55 e0             	mov    %edx,-0x20(%ebp)
c01035e4:	89 45 dc             	mov    %eax,-0x24(%ebp)
    __list_add(elm, listelm, listelm->next);
c01035e7:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01035ea:	8b 40 04             	mov    0x4(%eax),%eax
c01035ed:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01035f0:	89 55 d8             	mov    %edx,-0x28(%ebp)
c01035f3:	8b 55 e0             	mov    -0x20(%ebp),%edx
c01035f6:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c01035f9:	89 45 d0             	mov    %eax,-0x30(%ebp)
    prev->next = next->prev = elm;
c01035fc:	8b 45 d0             	mov    -0x30(%ebp),%eax
c01035ff:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0103602:	89 10                	mov    %edx,(%eax)
c0103604:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0103607:	8b 10                	mov    (%eax),%edx
c0103609:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c010360c:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c010360f:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0103612:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0103615:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0103618:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010361b:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010361e:	89 10                	mov    %edx,(%eax)
}
c0103620:	90                   	nop
}
c0103621:	90                   	nop
    }
        list_del(&(page->page_link));
c0103622:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103625:	83 c0 0c             	add    $0xc,%eax
c0103628:	89 45 bc             	mov    %eax,-0x44(%ebp)
    __list_del(listelm->prev, listelm->next);
c010362b:	8b 45 bc             	mov    -0x44(%ebp),%eax
c010362e:	8b 40 04             	mov    0x4(%eax),%eax
c0103631:	8b 55 bc             	mov    -0x44(%ebp),%edx
c0103634:	8b 12                	mov    (%edx),%edx
c0103636:	89 55 b8             	mov    %edx,-0x48(%ebp)
c0103639:	89 45 b4             	mov    %eax,-0x4c(%ebp)
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 * */
static inline void
__list_del(list_entry_t *prev, list_entry_t *next) {
    prev->next = next;
c010363c:	8b 45 b8             	mov    -0x48(%ebp),%eax
c010363f:	8b 55 b4             	mov    -0x4c(%ebp),%edx
c0103642:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c0103645:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0103648:	8b 55 b8             	mov    -0x48(%ebp),%edx
c010364b:	89 10                	mov    %edx,(%eax)
}
c010364d:	90                   	nop
}
c010364e:	90                   	nop
        nr_free -= n;// 减少空闲页的计数
c010364f:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
c0103654:	2b 45 08             	sub    0x8(%ebp),%eax
c0103657:	a3 ec bf 12 c0       	mov    %eax,0xc012bfec
        ClearPageProperty(page);// 清除已分配页的属性
c010365c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010365f:	83 c0 04             	add    $0x4,%eax
c0103662:	c7 45 c4 01 00 00 00 	movl   $0x1,-0x3c(%ebp)
c0103669:	89 45 c0             	mov    %eax,-0x40(%ebp)
    asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c010366c:	8b 45 c0             	mov    -0x40(%ebp),%eax
c010366f:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c0103672:	0f b3 10             	btr    %edx,(%eax)
}
c0103675:	90                   	nop
    }
    return page;// 返回分配的页块
c0103676:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0103679:	89 ec                	mov    %ebp,%esp
c010367b:	5d                   	pop    %ebp
c010367c:	c3                   	ret    

c010367d <default_free_pages>:

static void
default_free_pages(struct Page *base, size_t n) {
c010367d:	55                   	push   %ebp
c010367e:	89 e5                	mov    %esp,%ebp
c0103680:	81 ec 98 00 00 00    	sub    $0x98,%esp
    assert(n > 0);// 确保请求释放的页数大于零
c0103686:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c010368a:	75 24                	jne    c01036b0 <default_free_pages+0x33>
c010368c:	c7 44 24 0c 70 a9 10 	movl   $0xc010a970,0xc(%esp)
c0103693:	c0 
c0103694:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c010369b:	c0 
c010369c:	c7 44 24 04 cb 00 00 	movl   $0xcb,0x4(%esp)
c01036a3:	00 
c01036a4:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c01036ab:	e8 95 d5 ff ff       	call   c0100c45 <__panic>
    struct Page *p = base;
c01036b0:	8b 45 08             	mov    0x8(%ebp),%eax
c01036b3:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 遍历释放的页，检查状态并重置
    for (; p != base + n; p ++) {
c01036b6:	e9 9d 00 00 00       	jmp    c0103758 <default_free_pages+0xdb>
        assert(!PageReserved(p) && !PageProperty(p));// 确保页没有被保留并且没有属性
c01036bb:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01036be:	83 c0 04             	add    $0x4,%eax
c01036c1:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c01036c8:	89 45 e8             	mov    %eax,-0x18(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c01036cb:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01036ce:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01036d1:	0f a3 10             	bt     %edx,(%eax)
c01036d4:	19 c0                	sbb    %eax,%eax
c01036d6:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    return oldbit != 0;
c01036d9:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c01036dd:	0f 95 c0             	setne  %al
c01036e0:	0f b6 c0             	movzbl %al,%eax
c01036e3:	85 c0                	test   %eax,%eax
c01036e5:	75 2c                	jne    c0103713 <default_free_pages+0x96>
c01036e7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01036ea:	83 c0 04             	add    $0x4,%eax
c01036ed:	c7 45 e0 01 00 00 00 	movl   $0x1,-0x20(%ebp)
c01036f4:	89 45 dc             	mov    %eax,-0x24(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c01036f7:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01036fa:	8b 55 e0             	mov    -0x20(%ebp),%edx
c01036fd:	0f a3 10             	bt     %edx,(%eax)
c0103700:	19 c0                	sbb    %eax,%eax
c0103702:	89 45 d8             	mov    %eax,-0x28(%ebp)
    return oldbit != 0;
c0103705:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
c0103709:	0f 95 c0             	setne  %al
c010370c:	0f b6 c0             	movzbl %al,%eax
c010370f:	85 c0                	test   %eax,%eax
c0103711:	74 24                	je     c0103737 <default_free_pages+0xba>
c0103713:	c7 44 24 0c b4 a9 10 	movl   $0xc010a9b4,0xc(%esp)
c010371a:	c0 
c010371b:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103722:	c0 
c0103723:	c7 44 24 04 cf 00 00 	movl   $0xcf,0x4(%esp)
c010372a:	00 
c010372b:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103732:	e8 0e d5 ff ff       	call   c0100c45 <__panic>
        p->flags = 0;// 清除 flags 字段
c0103737:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010373a:	c7 40 04 00 00 00 00 	movl   $0x0,0x4(%eax)
        set_page_ref(p, 0);// 清除引用计数
c0103741:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0103748:	00 
c0103749:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010374c:	89 04 24             	mov    %eax,(%esp)
c010374f:	e8 19 fc ff ff       	call   c010336d <set_page_ref>
    for (; p != base + n; p ++) {
c0103754:	83 45 f4 20          	addl   $0x20,-0xc(%ebp)
c0103758:	8b 45 0c             	mov    0xc(%ebp),%eax
c010375b:	c1 e0 05             	shl    $0x5,%eax
c010375e:	89 c2                	mov    %eax,%edx
c0103760:	8b 45 08             	mov    0x8(%ebp),%eax
c0103763:	01 d0                	add    %edx,%eax
c0103765:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0103768:	0f 85 4d ff ff ff    	jne    c01036bb <default_free_pages+0x3e>
    }
    // 设置基页的属性为释放的页数
    base->property = n;
c010376e:	8b 45 08             	mov    0x8(%ebp),%eax
c0103771:	8b 55 0c             	mov    0xc(%ebp),%edx
c0103774:	89 50 08             	mov    %edx,0x8(%eax)
    SetPageProperty(base);// 设置页的有效标志
c0103777:	8b 45 08             	mov    0x8(%ebp),%eax
c010377a:	83 c0 04             	add    $0x4,%eax
c010377d:	c7 45 d0 01 00 00 00 	movl   $0x1,-0x30(%ebp)
c0103784:	89 45 cc             	mov    %eax,-0x34(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0103787:	8b 45 cc             	mov    -0x34(%ebp),%eax
c010378a:	8b 55 d0             	mov    -0x30(%ebp),%edx
c010378d:	0f ab 10             	bts    %edx,(%eax)
}
c0103790:	90                   	nop
c0103791:	c7 45 d4 e4 bf 12 c0 	movl   $0xc012bfe4,-0x2c(%ebp)
    return listelm->next;
c0103798:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c010379b:	8b 40 04             	mov    0x4(%eax),%eax
    // 遍历空闲列表，检查是否需要合并
    list_entry_t *le = list_next(&free_list);
c010379e:	89 45 f0             	mov    %eax,-0x10(%ebp)
    while (le != &free_list) {
c01037a1:	e9 00 01 00 00       	jmp    c01038a6 <default_free_pages+0x229>
        p = le2page(le, page_link);
c01037a6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01037a9:	83 e8 0c             	sub    $0xc,%eax
c01037ac:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01037af:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01037b2:	89 45 c8             	mov    %eax,-0x38(%ebp)
c01037b5:	8b 45 c8             	mov    -0x38(%ebp),%eax
c01037b8:	8b 40 04             	mov    0x4(%eax),%eax
        le = list_next(le);
c01037bb:	89 45 f0             	mov    %eax,-0x10(%ebp)
        // 如果当前页块与释放的页块相邻，合并
        if (base + base->property == p) {
c01037be:	8b 45 08             	mov    0x8(%ebp),%eax
c01037c1:	8b 40 08             	mov    0x8(%eax),%eax
c01037c4:	c1 e0 05             	shl    $0x5,%eax
c01037c7:	89 c2                	mov    %eax,%edx
c01037c9:	8b 45 08             	mov    0x8(%ebp),%eax
c01037cc:	01 d0                	add    %edx,%eax
c01037ce:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c01037d1:	75 5d                	jne    c0103830 <default_free_pages+0x1b3>
            base->property += p->property;// 合并当前页块
c01037d3:	8b 45 08             	mov    0x8(%ebp),%eax
c01037d6:	8b 50 08             	mov    0x8(%eax),%edx
c01037d9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01037dc:	8b 40 08             	mov    0x8(%eax),%eax
c01037df:	01 c2                	add    %eax,%edx
c01037e1:	8b 45 08             	mov    0x8(%ebp),%eax
c01037e4:	89 50 08             	mov    %edx,0x8(%eax)
            ClearPageProperty(p);// 清除合并页的属性
c01037e7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01037ea:	83 c0 04             	add    $0x4,%eax
c01037ed:	c7 45 b8 01 00 00 00 	movl   $0x1,-0x48(%ebp)
c01037f4:	89 45 b4             	mov    %eax,-0x4c(%ebp)
    asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c01037f7:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c01037fa:	8b 55 b8             	mov    -0x48(%ebp),%edx
c01037fd:	0f b3 10             	btr    %edx,(%eax)
}
c0103800:	90                   	nop
            list_del(&(p->page_link));// 从空闲列表中删除合并页
c0103801:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103804:	83 c0 0c             	add    $0xc,%eax
c0103807:	89 45 c4             	mov    %eax,-0x3c(%ebp)
    __list_del(listelm->prev, listelm->next);
c010380a:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c010380d:	8b 40 04             	mov    0x4(%eax),%eax
c0103810:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c0103813:	8b 12                	mov    (%edx),%edx
c0103815:	89 55 c0             	mov    %edx,-0x40(%ebp)
c0103818:	89 45 bc             	mov    %eax,-0x44(%ebp)
    prev->next = next;
c010381b:	8b 45 c0             	mov    -0x40(%ebp),%eax
c010381e:	8b 55 bc             	mov    -0x44(%ebp),%edx
c0103821:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c0103824:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0103827:	8b 55 c0             	mov    -0x40(%ebp),%edx
c010382a:	89 10                	mov    %edx,(%eax)
}
c010382c:	90                   	nop
}
c010382d:	90                   	nop
c010382e:	eb 76                	jmp    c01038a6 <default_free_pages+0x229>
        }
        else if (p + p->property == base) {
c0103830:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103833:	8b 40 08             	mov    0x8(%eax),%eax
c0103836:	c1 e0 05             	shl    $0x5,%eax
c0103839:	89 c2                	mov    %eax,%edx
c010383b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010383e:	01 d0                	add    %edx,%eax
c0103840:	39 45 08             	cmp    %eax,0x8(%ebp)
c0103843:	75 61                	jne    c01038a6 <default_free_pages+0x229>
            p->property += base->property;// 合并前一个页块
c0103845:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103848:	8b 50 08             	mov    0x8(%eax),%edx
c010384b:	8b 45 08             	mov    0x8(%ebp),%eax
c010384e:	8b 40 08             	mov    0x8(%eax),%eax
c0103851:	01 c2                	add    %eax,%edx
c0103853:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103856:	89 50 08             	mov    %edx,0x8(%eax)
            ClearPageProperty(base);// 清除当前页的属性
c0103859:	8b 45 08             	mov    0x8(%ebp),%eax
c010385c:	83 c0 04             	add    $0x4,%eax
c010385f:	c7 45 a4 01 00 00 00 	movl   $0x1,-0x5c(%ebp)
c0103866:	89 45 a0             	mov    %eax,-0x60(%ebp)
    asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c0103869:	8b 45 a0             	mov    -0x60(%ebp),%eax
c010386c:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c010386f:	0f b3 10             	btr    %edx,(%eax)
}
c0103872:	90                   	nop
            base = p;// 更新 base 指针
c0103873:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103876:	89 45 08             	mov    %eax,0x8(%ebp)
            list_del(&(p->page_link));// 从空闲列表中删除当前页
c0103879:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010387c:	83 c0 0c             	add    $0xc,%eax
c010387f:	89 45 b0             	mov    %eax,-0x50(%ebp)
    __list_del(listelm->prev, listelm->next);
c0103882:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0103885:	8b 40 04             	mov    0x4(%eax),%eax
c0103888:	8b 55 b0             	mov    -0x50(%ebp),%edx
c010388b:	8b 12                	mov    (%edx),%edx
c010388d:	89 55 ac             	mov    %edx,-0x54(%ebp)
c0103890:	89 45 a8             	mov    %eax,-0x58(%ebp)
    prev->next = next;
c0103893:	8b 45 ac             	mov    -0x54(%ebp),%eax
c0103896:	8b 55 a8             	mov    -0x58(%ebp),%edx
c0103899:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c010389c:	8b 45 a8             	mov    -0x58(%ebp),%eax
c010389f:	8b 55 ac             	mov    -0x54(%ebp),%edx
c01038a2:	89 10                	mov    %edx,(%eax)
}
c01038a4:	90                   	nop
}
c01038a5:	90                   	nop
    while (le != &free_list) {
c01038a6:	81 7d f0 e4 bf 12 c0 	cmpl   $0xc012bfe4,-0x10(%ebp)
c01038ad:	0f 85 f3 fe ff ff    	jne    c01037a6 <default_free_pages+0x129>
        }
    }
    nr_free += n;// 更新空闲页的计数
c01038b3:	8b 15 ec bf 12 c0    	mov    0xc012bfec,%edx
c01038b9:	8b 45 0c             	mov    0xc(%ebp),%eax
c01038bc:	01 d0                	add    %edx,%eax
c01038be:	a3 ec bf 12 c0       	mov    %eax,0xc012bfec
c01038c3:	c7 45 9c e4 bf 12 c0 	movl   $0xc012bfe4,-0x64(%ebp)
    return listelm->next;
c01038ca:	8b 45 9c             	mov    -0x64(%ebp),%eax
c01038cd:	8b 40 04             	mov    0x4(%eax),%eax
    le = list_next(&free_list);
c01038d0:	89 45 f0             	mov    %eax,-0x10(%ebp)
    while (le != &free_list)
c01038d3:	eb 66                	jmp    c010393b <default_free_pages+0x2be>
    {
        p = le2page(le, page_link);
c01038d5:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01038d8:	83 e8 0c             	sub    $0xc,%eax
c01038db:	89 45 f4             	mov    %eax,-0xc(%ebp)
        if (base + base->property <= p)
c01038de:	8b 45 08             	mov    0x8(%ebp),%eax
c01038e1:	8b 40 08             	mov    0x8(%eax),%eax
c01038e4:	c1 e0 05             	shl    $0x5,%eax
c01038e7:	89 c2                	mov    %eax,%edx
c01038e9:	8b 45 08             	mov    0x8(%ebp),%eax
c01038ec:	01 d0                	add    %edx,%eax
c01038ee:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c01038f1:	72 39                	jb     c010392c <default_free_pages+0x2af>
        {
            assert(base + base->property != p);
c01038f3:	8b 45 08             	mov    0x8(%ebp),%eax
c01038f6:	8b 40 08             	mov    0x8(%eax),%eax
c01038f9:	c1 e0 05             	shl    $0x5,%eax
c01038fc:	89 c2                	mov    %eax,%edx
c01038fe:	8b 45 08             	mov    0x8(%ebp),%eax
c0103901:	01 d0                	add    %edx,%eax
c0103903:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0103906:	75 3e                	jne    c0103946 <default_free_pages+0x2c9>
c0103908:	c7 44 24 0c d9 a9 10 	movl   $0xc010a9d9,0xc(%esp)
c010390f:	c0 
c0103910:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103917:	c0 
c0103918:	c7 44 24 04 ef 00 00 	movl   $0xef,0x4(%esp)
c010391f:	00 
c0103920:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103927:	e8 19 d3 ff ff       	call   c0100c45 <__panic>
c010392c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010392f:	89 45 98             	mov    %eax,-0x68(%ebp)
c0103932:	8b 45 98             	mov    -0x68(%ebp),%eax
c0103935:	8b 40 04             	mov    0x4(%eax),%eax
            break;
        }
        le = list_next(le);    
c0103938:	89 45 f0             	mov    %eax,-0x10(%ebp)
    while (le != &free_list)
c010393b:	81 7d f0 e4 bf 12 c0 	cmpl   $0xc012bfe4,-0x10(%ebp)
c0103942:	75 91                	jne    c01038d5 <default_free_pages+0x258>
c0103944:	eb 01                	jmp    c0103947 <default_free_pages+0x2ca>
            break;
c0103946:	90                   	nop
    }
    
    list_add_before(le, &(base->page_link));// 将释放的页块添加到空闲列表中
c0103947:	8b 45 08             	mov    0x8(%ebp),%eax
c010394a:	8d 50 0c             	lea    0xc(%eax),%edx
c010394d:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103950:	89 45 94             	mov    %eax,-0x6c(%ebp)
c0103953:	89 55 90             	mov    %edx,-0x70(%ebp)
    __list_add(elm, listelm->prev, listelm);
c0103956:	8b 45 94             	mov    -0x6c(%ebp),%eax
c0103959:	8b 00                	mov    (%eax),%eax
c010395b:	8b 55 90             	mov    -0x70(%ebp),%edx
c010395e:	89 55 8c             	mov    %edx,-0x74(%ebp)
c0103961:	89 45 88             	mov    %eax,-0x78(%ebp)
c0103964:	8b 45 94             	mov    -0x6c(%ebp),%eax
c0103967:	89 45 84             	mov    %eax,-0x7c(%ebp)
    prev->next = next->prev = elm;
c010396a:	8b 45 84             	mov    -0x7c(%ebp),%eax
c010396d:	8b 55 8c             	mov    -0x74(%ebp),%edx
c0103970:	89 10                	mov    %edx,(%eax)
c0103972:	8b 45 84             	mov    -0x7c(%ebp),%eax
c0103975:	8b 10                	mov    (%eax),%edx
c0103977:	8b 45 88             	mov    -0x78(%ebp),%eax
c010397a:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c010397d:	8b 45 8c             	mov    -0x74(%ebp),%eax
c0103980:	8b 55 84             	mov    -0x7c(%ebp),%edx
c0103983:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0103986:	8b 45 8c             	mov    -0x74(%ebp),%eax
c0103989:	8b 55 88             	mov    -0x78(%ebp),%edx
c010398c:	89 10                	mov    %edx,(%eax)
}
c010398e:	90                   	nop
}
c010398f:	90                   	nop
}
c0103990:	90                   	nop
c0103991:	89 ec                	mov    %ebp,%esp
c0103993:	5d                   	pop    %ebp
c0103994:	c3                   	ret    

c0103995 <default_nr_free_pages>:

//用于返回当前系统中可用的空闲页的数量。
static size_t
default_nr_free_pages(void) {
c0103995:	55                   	push   %ebp
c0103996:	89 e5                	mov    %esp,%ebp
    return nr_free;// 返回当前空闲页的数量
c0103998:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
}
c010399d:	5d                   	pop    %ebp
c010399e:	c3                   	ret    

c010399f <basic_check>:

//basic_check 函数用于测试内存分配和释放的基本功能，
//确保在不同情况下内存管理系统的正确性，包括分配、释放、合并和引用计数等操作。
static void
basic_check(void) {
c010399f:	55                   	push   %ebp
c01039a0:	89 e5                	mov    %esp,%ebp
c01039a2:	83 ec 48             	sub    $0x48,%esp
    struct Page *p0, *p1, *p2;
    p0 = p1 = p2 = NULL;
c01039a5:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c01039ac:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01039af:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01039b2:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01039b5:	89 45 ec             	mov    %eax,-0x14(%ebp)
    // 分配三个页面
    assert((p0 = alloc_page()) != NULL);
c01039b8:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01039bf:	e8 17 16 00 00       	call   c0104fdb <alloc_pages>
c01039c4:	89 45 ec             	mov    %eax,-0x14(%ebp)
c01039c7:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c01039cb:	75 24                	jne    c01039f1 <basic_check+0x52>
c01039cd:	c7 44 24 0c f4 a9 10 	movl   $0xc010a9f4,0xc(%esp)
c01039d4:	c0 
c01039d5:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c01039dc:	c0 
c01039dd:	c7 44 24 04 05 01 00 	movl   $0x105,0x4(%esp)
c01039e4:	00 
c01039e5:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c01039ec:	e8 54 d2 ff ff       	call   c0100c45 <__panic>
    assert((p1 = alloc_page()) != NULL);
c01039f1:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01039f8:	e8 de 15 00 00       	call   c0104fdb <alloc_pages>
c01039fd:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0103a00:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0103a04:	75 24                	jne    c0103a2a <basic_check+0x8b>
c0103a06:	c7 44 24 0c 10 aa 10 	movl   $0xc010aa10,0xc(%esp)
c0103a0d:	c0 
c0103a0e:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103a15:	c0 
c0103a16:	c7 44 24 04 06 01 00 	movl   $0x106,0x4(%esp)
c0103a1d:	00 
c0103a1e:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103a25:	e8 1b d2 ff ff       	call   c0100c45 <__panic>
    assert((p2 = alloc_page()) != NULL);
c0103a2a:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103a31:	e8 a5 15 00 00       	call   c0104fdb <alloc_pages>
c0103a36:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0103a39:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0103a3d:	75 24                	jne    c0103a63 <basic_check+0xc4>
c0103a3f:	c7 44 24 0c 2c aa 10 	movl   $0xc010aa2c,0xc(%esp)
c0103a46:	c0 
c0103a47:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103a4e:	c0 
c0103a4f:	c7 44 24 04 07 01 00 	movl   $0x107,0x4(%esp)
c0103a56:	00 
c0103a57:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103a5e:	e8 e2 d1 ff ff       	call   c0100c45 <__panic>
     // 确保所有分配的页面是不同的
    assert(p0 != p1 && p0 != p2 && p1 != p2);
c0103a63:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103a66:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c0103a69:	74 10                	je     c0103a7b <basic_check+0xdc>
c0103a6b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103a6e:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0103a71:	74 08                	je     c0103a7b <basic_check+0xdc>
c0103a73:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103a76:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0103a79:	75 24                	jne    c0103a9f <basic_check+0x100>
c0103a7b:	c7 44 24 0c 48 aa 10 	movl   $0xc010aa48,0xc(%esp)
c0103a82:	c0 
c0103a83:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103a8a:	c0 
c0103a8b:	c7 44 24 04 09 01 00 	movl   $0x109,0x4(%esp)
c0103a92:	00 
c0103a93:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103a9a:	e8 a6 d1 ff ff       	call   c0100c45 <__panic>
    // 确保页面的引用计数为 0
    assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0);
c0103a9f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103aa2:	89 04 24             	mov    %eax,(%esp)
c0103aa5:	e8 b9 f8 ff ff       	call   c0103363 <page_ref>
c0103aaa:	85 c0                	test   %eax,%eax
c0103aac:	75 1e                	jne    c0103acc <basic_check+0x12d>
c0103aae:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103ab1:	89 04 24             	mov    %eax,(%esp)
c0103ab4:	e8 aa f8 ff ff       	call   c0103363 <page_ref>
c0103ab9:	85 c0                	test   %eax,%eax
c0103abb:	75 0f                	jne    c0103acc <basic_check+0x12d>
c0103abd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103ac0:	89 04 24             	mov    %eax,(%esp)
c0103ac3:	e8 9b f8 ff ff       	call   c0103363 <page_ref>
c0103ac8:	85 c0                	test   %eax,%eax
c0103aca:	74 24                	je     c0103af0 <basic_check+0x151>
c0103acc:	c7 44 24 0c 6c aa 10 	movl   $0xc010aa6c,0xc(%esp)
c0103ad3:	c0 
c0103ad4:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103adb:	c0 
c0103adc:	c7 44 24 04 0b 01 00 	movl   $0x10b,0x4(%esp)
c0103ae3:	00 
c0103ae4:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103aeb:	e8 55 d1 ff ff       	call   c0100c45 <__panic>
    // 确保页面地址在合法范围内
    assert(page2pa(p0) < npage * PGSIZE);
c0103af0:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103af3:	89 04 24             	mov    %eax,(%esp)
c0103af6:	e8 50 f8 ff ff       	call   c010334b <page2pa>
c0103afb:	8b 15 04 c0 12 c0    	mov    0xc012c004,%edx
c0103b01:	c1 e2 0c             	shl    $0xc,%edx
c0103b04:	39 d0                	cmp    %edx,%eax
c0103b06:	72 24                	jb     c0103b2c <basic_check+0x18d>
c0103b08:	c7 44 24 0c a8 aa 10 	movl   $0xc010aaa8,0xc(%esp)
c0103b0f:	c0 
c0103b10:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103b17:	c0 
c0103b18:	c7 44 24 04 0d 01 00 	movl   $0x10d,0x4(%esp)
c0103b1f:	00 
c0103b20:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103b27:	e8 19 d1 ff ff       	call   c0100c45 <__panic>
    assert(page2pa(p1) < npage * PGSIZE);
c0103b2c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103b2f:	89 04 24             	mov    %eax,(%esp)
c0103b32:	e8 14 f8 ff ff       	call   c010334b <page2pa>
c0103b37:	8b 15 04 c0 12 c0    	mov    0xc012c004,%edx
c0103b3d:	c1 e2 0c             	shl    $0xc,%edx
c0103b40:	39 d0                	cmp    %edx,%eax
c0103b42:	72 24                	jb     c0103b68 <basic_check+0x1c9>
c0103b44:	c7 44 24 0c c5 aa 10 	movl   $0xc010aac5,0xc(%esp)
c0103b4b:	c0 
c0103b4c:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103b53:	c0 
c0103b54:	c7 44 24 04 0e 01 00 	movl   $0x10e,0x4(%esp)
c0103b5b:	00 
c0103b5c:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103b63:	e8 dd d0 ff ff       	call   c0100c45 <__panic>
    assert(page2pa(p2) < npage * PGSIZE);
c0103b68:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103b6b:	89 04 24             	mov    %eax,(%esp)
c0103b6e:	e8 d8 f7 ff ff       	call   c010334b <page2pa>
c0103b73:	8b 15 04 c0 12 c0    	mov    0xc012c004,%edx
c0103b79:	c1 e2 0c             	shl    $0xc,%edx
c0103b7c:	39 d0                	cmp    %edx,%eax
c0103b7e:	72 24                	jb     c0103ba4 <basic_check+0x205>
c0103b80:	c7 44 24 0c e2 aa 10 	movl   $0xc010aae2,0xc(%esp)
c0103b87:	c0 
c0103b88:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103b8f:	c0 
c0103b90:	c7 44 24 04 0f 01 00 	movl   $0x10f,0x4(%esp)
c0103b97:	00 
c0103b98:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103b9f:	e8 a1 d0 ff ff       	call   c0100c45 <__panic>
    // 保存当前的空闲页面链表和数量
    list_entry_t free_list_store = free_list;
c0103ba4:	a1 e4 bf 12 c0       	mov    0xc012bfe4,%eax
c0103ba9:	8b 15 e8 bf 12 c0    	mov    0xc012bfe8,%edx
c0103baf:	89 45 d0             	mov    %eax,-0x30(%ebp)
c0103bb2:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c0103bb5:	c7 45 dc e4 bf 12 c0 	movl   $0xc012bfe4,-0x24(%ebp)
    elm->prev = elm->next = elm;
c0103bbc:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0103bbf:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0103bc2:	89 50 04             	mov    %edx,0x4(%eax)
c0103bc5:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0103bc8:	8b 50 04             	mov    0x4(%eax),%edx
c0103bcb:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0103bce:	89 10                	mov    %edx,(%eax)
}
c0103bd0:	90                   	nop
c0103bd1:	c7 45 e0 e4 bf 12 c0 	movl   $0xc012bfe4,-0x20(%ebp)
    return list->next == list;
c0103bd8:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0103bdb:	8b 40 04             	mov    0x4(%eax),%eax
c0103bde:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c0103be1:	0f 94 c0             	sete   %al
c0103be4:	0f b6 c0             	movzbl %al,%eax
    list_init(&free_list);// 初始化空闲列表
    assert(list_empty(&free_list));// 确保空闲列表为空
c0103be7:	85 c0                	test   %eax,%eax
c0103be9:	75 24                	jne    c0103c0f <basic_check+0x270>
c0103beb:	c7 44 24 0c ff aa 10 	movl   $0xc010aaff,0xc(%esp)
c0103bf2:	c0 
c0103bf3:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103bfa:	c0 
c0103bfb:	c7 44 24 04 13 01 00 	movl   $0x113,0x4(%esp)
c0103c02:	00 
c0103c03:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103c0a:	e8 36 d0 ff ff       	call   c0100c45 <__panic>

    unsigned int nr_free_store = nr_free;// 保存当前空闲页数量
c0103c0f:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
c0103c14:	89 45 e8             	mov    %eax,-0x18(%ebp)
    nr_free = 0;// 将空闲页数量设为 0
c0103c17:	c7 05 ec bf 12 c0 00 	movl   $0x0,0xc012bfec
c0103c1e:	00 00 00 
    // 请求分配页面，但当前没有空闲页面
    assert(alloc_page() == NULL);
c0103c21:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103c28:	e8 ae 13 00 00       	call   c0104fdb <alloc_pages>
c0103c2d:	85 c0                	test   %eax,%eax
c0103c2f:	74 24                	je     c0103c55 <basic_check+0x2b6>
c0103c31:	c7 44 24 0c 16 ab 10 	movl   $0xc010ab16,0xc(%esp)
c0103c38:	c0 
c0103c39:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103c40:	c0 
c0103c41:	c7 44 24 04 18 01 00 	movl   $0x118,0x4(%esp)
c0103c48:	00 
c0103c49:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103c50:	e8 f0 cf ff ff       	call   c0100c45 <__panic>
    // 释放之前分配的页面
    free_page(p0);
c0103c55:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103c5c:	00 
c0103c5d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103c60:	89 04 24             	mov    %eax,(%esp)
c0103c63:	e8 e0 13 00 00       	call   c0105048 <free_pages>
    free_page(p1);
c0103c68:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103c6f:	00 
c0103c70:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103c73:	89 04 24             	mov    %eax,(%esp)
c0103c76:	e8 cd 13 00 00       	call   c0105048 <free_pages>
    free_page(p2);
c0103c7b:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103c82:	00 
c0103c83:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103c86:	89 04 24             	mov    %eax,(%esp)
c0103c89:	e8 ba 13 00 00       	call   c0105048 <free_pages>
    assert(nr_free == 3);// 确保释放后空闲页数量为 3
c0103c8e:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
c0103c93:	83 f8 03             	cmp    $0x3,%eax
c0103c96:	74 24                	je     c0103cbc <basic_check+0x31d>
c0103c98:	c7 44 24 0c 2b ab 10 	movl   $0xc010ab2b,0xc(%esp)
c0103c9f:	c0 
c0103ca0:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103ca7:	c0 
c0103ca8:	c7 44 24 04 1d 01 00 	movl   $0x11d,0x4(%esp)
c0103caf:	00 
c0103cb0:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103cb7:	e8 89 cf ff ff       	call   c0100c45 <__panic>
    // 再次分配三个页面
    assert((p0 = alloc_page()) != NULL);
c0103cbc:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103cc3:	e8 13 13 00 00       	call   c0104fdb <alloc_pages>
c0103cc8:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0103ccb:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0103ccf:	75 24                	jne    c0103cf5 <basic_check+0x356>
c0103cd1:	c7 44 24 0c f4 a9 10 	movl   $0xc010a9f4,0xc(%esp)
c0103cd8:	c0 
c0103cd9:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103ce0:	c0 
c0103ce1:	c7 44 24 04 1f 01 00 	movl   $0x11f,0x4(%esp)
c0103ce8:	00 
c0103ce9:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103cf0:	e8 50 cf ff ff       	call   c0100c45 <__panic>
    assert((p1 = alloc_page()) != NULL);
c0103cf5:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103cfc:	e8 da 12 00 00       	call   c0104fdb <alloc_pages>
c0103d01:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0103d04:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0103d08:	75 24                	jne    c0103d2e <basic_check+0x38f>
c0103d0a:	c7 44 24 0c 10 aa 10 	movl   $0xc010aa10,0xc(%esp)
c0103d11:	c0 
c0103d12:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103d19:	c0 
c0103d1a:	c7 44 24 04 20 01 00 	movl   $0x120,0x4(%esp)
c0103d21:	00 
c0103d22:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103d29:	e8 17 cf ff ff       	call   c0100c45 <__panic>
    assert((p2 = alloc_page()) != NULL);
c0103d2e:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103d35:	e8 a1 12 00 00       	call   c0104fdb <alloc_pages>
c0103d3a:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0103d3d:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0103d41:	75 24                	jne    c0103d67 <basic_check+0x3c8>
c0103d43:	c7 44 24 0c 2c aa 10 	movl   $0xc010aa2c,0xc(%esp)
c0103d4a:	c0 
c0103d4b:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103d52:	c0 
c0103d53:	c7 44 24 04 21 01 00 	movl   $0x121,0x4(%esp)
c0103d5a:	00 
c0103d5b:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103d62:	e8 de ce ff ff       	call   c0100c45 <__panic>
    // 测试空闲页面是否不足
    assert(alloc_page() == NULL);
c0103d67:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103d6e:	e8 68 12 00 00       	call   c0104fdb <alloc_pages>
c0103d73:	85 c0                	test   %eax,%eax
c0103d75:	74 24                	je     c0103d9b <basic_check+0x3fc>
c0103d77:	c7 44 24 0c 16 ab 10 	movl   $0xc010ab16,0xc(%esp)
c0103d7e:	c0 
c0103d7f:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103d86:	c0 
c0103d87:	c7 44 24 04 23 01 00 	movl   $0x123,0x4(%esp)
c0103d8e:	00 
c0103d8f:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103d96:	e8 aa ce ff ff       	call   c0100c45 <__panic>
    // 释放 p0，并检查空闲列表
    free_page(p0);
c0103d9b:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103da2:	00 
c0103da3:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103da6:	89 04 24             	mov    %eax,(%esp)
c0103da9:	e8 9a 12 00 00       	call   c0105048 <free_pages>
c0103dae:	c7 45 d8 e4 bf 12 c0 	movl   $0xc012bfe4,-0x28(%ebp)
c0103db5:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0103db8:	8b 40 04             	mov    0x4(%eax),%eax
c0103dbb:	39 45 d8             	cmp    %eax,-0x28(%ebp)
c0103dbe:	0f 94 c0             	sete   %al
c0103dc1:	0f b6 c0             	movzbl %al,%eax
    assert(!list_empty(&free_list));// 确保空闲列表不为空
c0103dc4:	85 c0                	test   %eax,%eax
c0103dc6:	74 24                	je     c0103dec <basic_check+0x44d>
c0103dc8:	c7 44 24 0c 38 ab 10 	movl   $0xc010ab38,0xc(%esp)
c0103dcf:	c0 
c0103dd0:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103dd7:	c0 
c0103dd8:	c7 44 24 04 26 01 00 	movl   $0x126,0x4(%esp)
c0103ddf:	00 
c0103de0:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103de7:	e8 59 ce ff ff       	call   c0100c45 <__panic>

    struct Page *p;
    // 重新分配 p0，确保取回的是相同的页面
    assert((p = alloc_page()) == p0);
c0103dec:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103df3:	e8 e3 11 00 00       	call   c0104fdb <alloc_pages>
c0103df8:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0103dfb:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0103dfe:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0103e01:	74 24                	je     c0103e27 <basic_check+0x488>
c0103e03:	c7 44 24 0c 50 ab 10 	movl   $0xc010ab50,0xc(%esp)
c0103e0a:	c0 
c0103e0b:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103e12:	c0 
c0103e13:	c7 44 24 04 2a 01 00 	movl   $0x12a,0x4(%esp)
c0103e1a:	00 
c0103e1b:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103e22:	e8 1e ce ff ff       	call   c0100c45 <__panic>
    assert(alloc_page() == NULL);// 确保没有更多的页面可分配
c0103e27:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0103e2e:	e8 a8 11 00 00       	call   c0104fdb <alloc_pages>
c0103e33:	85 c0                	test   %eax,%eax
c0103e35:	74 24                	je     c0103e5b <basic_check+0x4bc>
c0103e37:	c7 44 24 0c 16 ab 10 	movl   $0xc010ab16,0xc(%esp)
c0103e3e:	c0 
c0103e3f:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103e46:	c0 
c0103e47:	c7 44 24 04 2b 01 00 	movl   $0x12b,0x4(%esp)
c0103e4e:	00 
c0103e4f:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103e56:	e8 ea cd ff ff       	call   c0100c45 <__panic>

    assert(nr_free == 0);// 确保当前空闲页面数量为 0
c0103e5b:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
c0103e60:	85 c0                	test   %eax,%eax
c0103e62:	74 24                	je     c0103e88 <basic_check+0x4e9>
c0103e64:	c7 44 24 0c 69 ab 10 	movl   $0xc010ab69,0xc(%esp)
c0103e6b:	c0 
c0103e6c:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103e73:	c0 
c0103e74:	c7 44 24 04 2d 01 00 	movl   $0x12d,0x4(%esp)
c0103e7b:	00 
c0103e7c:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103e83:	e8 bd cd ff ff       	call   c0100c45 <__panic>
    // 恢复之前的空闲页面链表和数量
    free_list = free_list_store;
c0103e88:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0103e8b:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0103e8e:	a3 e4 bf 12 c0       	mov    %eax,0xc012bfe4
c0103e93:	89 15 e8 bf 12 c0    	mov    %edx,0xc012bfe8
    nr_free = nr_free_store;
c0103e99:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0103e9c:	a3 ec bf 12 c0       	mov    %eax,0xc012bfec
    // 释放最后的页面
    free_page(p);
c0103ea1:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103ea8:	00 
c0103ea9:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0103eac:	89 04 24             	mov    %eax,(%esp)
c0103eaf:	e8 94 11 00 00       	call   c0105048 <free_pages>
    free_page(p1);
c0103eb4:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103ebb:	00 
c0103ebc:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103ebf:	89 04 24             	mov    %eax,(%esp)
c0103ec2:	e8 81 11 00 00       	call   c0105048 <free_pages>
    free_page(p2);
c0103ec7:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0103ece:	00 
c0103ecf:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0103ed2:	89 04 24             	mov    %eax,(%esp)
c0103ed5:	e8 6e 11 00 00       	call   c0105048 <free_pages>
}
c0103eda:	90                   	nop
c0103edb:	89 ec                	mov    %ebp,%esp
c0103edd:	5d                   	pop    %ebp
c0103ede:	c3                   	ret    

c0103edf <default_check>:

// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) 
// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions!
static void
default_check(void) {
c0103edf:	55                   	push   %ebp
c0103ee0:	89 e5                	mov    %esp,%ebp
c0103ee2:	81 ec 98 00 00 00    	sub    $0x98,%esp
    int count = 0, total = 0;
c0103ee8:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0103eef:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    list_entry_t *le = &free_list;
c0103ef6:	c7 45 ec e4 bf 12 c0 	movl   $0xc012bfe4,-0x14(%ebp)
    // 遍历空闲列表，计算空闲页面的数量和总属性值
    while ((le = list_next(le)) != &free_list) {
c0103efd:	eb 6a                	jmp    c0103f69 <default_check+0x8a>
        struct Page *p = le2page(le, page_link);
c0103eff:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103f02:	83 e8 0c             	sub    $0xc,%eax
c0103f05:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        assert(PageProperty(p));// 确保每个页面的属性是有效的
c0103f08:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0103f0b:	83 c0 04             	add    $0x4,%eax
c0103f0e:	c7 45 d0 01 00 00 00 	movl   $0x1,-0x30(%ebp)
c0103f15:	89 45 cc             	mov    %eax,-0x34(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0103f18:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0103f1b:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0103f1e:	0f a3 10             	bt     %edx,(%eax)
c0103f21:	19 c0                	sbb    %eax,%eax
c0103f23:	89 45 c8             	mov    %eax,-0x38(%ebp)
    return oldbit != 0;
c0103f26:	83 7d c8 00          	cmpl   $0x0,-0x38(%ebp)
c0103f2a:	0f 95 c0             	setne  %al
c0103f2d:	0f b6 c0             	movzbl %al,%eax
c0103f30:	85 c0                	test   %eax,%eax
c0103f32:	75 24                	jne    c0103f58 <default_check+0x79>
c0103f34:	c7 44 24 0c 76 ab 10 	movl   $0xc010ab76,0xc(%esp)
c0103f3b:	c0 
c0103f3c:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103f43:	c0 
c0103f44:	c7 44 24 04 40 01 00 	movl   $0x140,0x4(%esp)
c0103f4b:	00 
c0103f4c:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103f53:	e8 ed cc ff ff       	call   c0100c45 <__panic>
        count ++, total += p->property;// 累加页面属性
c0103f58:	ff 45 f4             	incl   -0xc(%ebp)
c0103f5b:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0103f5e:	8b 50 08             	mov    0x8(%eax),%edx
c0103f61:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0103f64:	01 d0                	add    %edx,%eax
c0103f66:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0103f69:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0103f6c:	89 45 c4             	mov    %eax,-0x3c(%ebp)
    return listelm->next;
c0103f6f:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0103f72:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != &free_list) {
c0103f75:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0103f78:	81 7d ec e4 bf 12 c0 	cmpl   $0xc012bfe4,-0x14(%ebp)
c0103f7f:	0f 85 7a ff ff ff    	jne    c0103eff <default_check+0x20>
    }
    // 确保总属性值与空闲页面数量匹配
    assert(total == nr_free_pages());
c0103f85:	e8 f3 10 00 00       	call   c010507d <nr_free_pages>
c0103f8a:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0103f8d:	39 d0                	cmp    %edx,%eax
c0103f8f:	74 24                	je     c0103fb5 <default_check+0xd6>
c0103f91:	c7 44 24 0c 86 ab 10 	movl   $0xc010ab86,0xc(%esp)
c0103f98:	c0 
c0103f99:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103fa0:	c0 
c0103fa1:	c7 44 24 04 44 01 00 	movl   $0x144,0x4(%esp)
c0103fa8:	00 
c0103fa9:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103fb0:	e8 90 cc ff ff       	call   c0100c45 <__panic>
    // 调用 basic_check 以验证基本的内存管理功能
    basic_check();
c0103fb5:	e8 e5 f9 ff ff       	call   c010399f <basic_check>
    // 分配 5 个页面
    struct Page *p0 = alloc_pages(5), *p1, *p2;
c0103fba:	c7 04 24 05 00 00 00 	movl   $0x5,(%esp)
c0103fc1:	e8 15 10 00 00       	call   c0104fdb <alloc_pages>
c0103fc6:	89 45 e8             	mov    %eax,-0x18(%ebp)
    assert(p0 != NULL);// 确保成功分配
c0103fc9:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0103fcd:	75 24                	jne    c0103ff3 <default_check+0x114>
c0103fcf:	c7 44 24 0c 9f ab 10 	movl   $0xc010ab9f,0xc(%esp)
c0103fd6:	c0 
c0103fd7:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0103fde:	c0 
c0103fdf:	c7 44 24 04 49 01 00 	movl   $0x149,0x4(%esp)
c0103fe6:	00 
c0103fe7:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0103fee:	e8 52 cc ff ff       	call   c0100c45 <__panic>
    assert(!PageProperty(p0));// 确保分配的页面不带属性
c0103ff3:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0103ff6:	83 c0 04             	add    $0x4,%eax
c0103ff9:	c7 45 c0 01 00 00 00 	movl   $0x1,-0x40(%ebp)
c0104000:	89 45 bc             	mov    %eax,-0x44(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0104003:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0104006:	8b 55 c0             	mov    -0x40(%ebp),%edx
c0104009:	0f a3 10             	bt     %edx,(%eax)
c010400c:	19 c0                	sbb    %eax,%eax
c010400e:	89 45 b8             	mov    %eax,-0x48(%ebp)
    return oldbit != 0;
c0104011:	83 7d b8 00          	cmpl   $0x0,-0x48(%ebp)
c0104015:	0f 95 c0             	setne  %al
c0104018:	0f b6 c0             	movzbl %al,%eax
c010401b:	85 c0                	test   %eax,%eax
c010401d:	74 24                	je     c0104043 <default_check+0x164>
c010401f:	c7 44 24 0c aa ab 10 	movl   $0xc010abaa,0xc(%esp)
c0104026:	c0 
c0104027:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c010402e:	c0 
c010402f:	c7 44 24 04 4a 01 00 	movl   $0x14a,0x4(%esp)
c0104036:	00 
c0104037:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c010403e:	e8 02 cc ff ff       	call   c0100c45 <__panic>
     // 初始化并检查空闲列表
    list_entry_t free_list_store = free_list;
c0104043:	a1 e4 bf 12 c0       	mov    0xc012bfe4,%eax
c0104048:	8b 15 e8 bf 12 c0    	mov    0xc012bfe8,%edx
c010404e:	89 45 80             	mov    %eax,-0x80(%ebp)
c0104051:	89 55 84             	mov    %edx,-0x7c(%ebp)
c0104054:	c7 45 b0 e4 bf 12 c0 	movl   $0xc012bfe4,-0x50(%ebp)
    elm->prev = elm->next = elm;
c010405b:	8b 45 b0             	mov    -0x50(%ebp),%eax
c010405e:	8b 55 b0             	mov    -0x50(%ebp),%edx
c0104061:	89 50 04             	mov    %edx,0x4(%eax)
c0104064:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0104067:	8b 50 04             	mov    0x4(%eax),%edx
c010406a:	8b 45 b0             	mov    -0x50(%ebp),%eax
c010406d:	89 10                	mov    %edx,(%eax)
}
c010406f:	90                   	nop
c0104070:	c7 45 b4 e4 bf 12 c0 	movl   $0xc012bfe4,-0x4c(%ebp)
    return list->next == list;
c0104077:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c010407a:	8b 40 04             	mov    0x4(%eax),%eax
c010407d:	39 45 b4             	cmp    %eax,-0x4c(%ebp)
c0104080:	0f 94 c0             	sete   %al
c0104083:	0f b6 c0             	movzbl %al,%eax
    list_init(&free_list);
    assert(list_empty(&free_list));// 确保空闲列表为空
c0104086:	85 c0                	test   %eax,%eax
c0104088:	75 24                	jne    c01040ae <default_check+0x1cf>
c010408a:	c7 44 24 0c ff aa 10 	movl   $0xc010aaff,0xc(%esp)
c0104091:	c0 
c0104092:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0104099:	c0 
c010409a:	c7 44 24 04 4e 01 00 	movl   $0x14e,0x4(%esp)
c01040a1:	00 
c01040a2:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c01040a9:	e8 97 cb ff ff       	call   c0100c45 <__panic>
    assert(alloc_page() == NULL);// 确保没有页面可分配
c01040ae:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01040b5:	e8 21 0f 00 00       	call   c0104fdb <alloc_pages>
c01040ba:	85 c0                	test   %eax,%eax
c01040bc:	74 24                	je     c01040e2 <default_check+0x203>
c01040be:	c7 44 24 0c 16 ab 10 	movl   $0xc010ab16,0xc(%esp)
c01040c5:	c0 
c01040c6:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c01040cd:	c0 
c01040ce:	c7 44 24 04 4f 01 00 	movl   $0x14f,0x4(%esp)
c01040d5:	00 
c01040d6:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c01040dd:	e8 63 cb ff ff       	call   c0100c45 <__panic>

    unsigned int nr_free_store = nr_free;// 保存当前空闲页数
c01040e2:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
c01040e7:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    nr_free = 0;// 将空闲页数设为 0
c01040ea:	c7 05 ec bf 12 c0 00 	movl   $0x0,0xc012bfec
c01040f1:	00 00 00 
    // 释放 3 个页面并确保分配页面时没有足够的空闲页
    free_pages(p0 + 2, 3);
c01040f4:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01040f7:	83 c0 40             	add    $0x40,%eax
c01040fa:	c7 44 24 04 03 00 00 	movl   $0x3,0x4(%esp)
c0104101:	00 
c0104102:	89 04 24             	mov    %eax,(%esp)
c0104105:	e8 3e 0f 00 00       	call   c0105048 <free_pages>
    assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面
c010410a:	c7 04 24 04 00 00 00 	movl   $0x4,(%esp)
c0104111:	e8 c5 0e 00 00       	call   c0104fdb <alloc_pages>
c0104116:	85 c0                	test   %eax,%eax
c0104118:	74 24                	je     c010413e <default_check+0x25f>
c010411a:	c7 44 24 0c bc ab 10 	movl   $0xc010abbc,0xc(%esp)
c0104121:	c0 
c0104122:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0104129:	c0 
c010412a:	c7 44 24 04 55 01 00 	movl   $0x155,0x4(%esp)
c0104131:	00 
c0104132:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0104139:	e8 07 cb ff ff       	call   c0100c45 <__panic>
    assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性
c010413e:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104141:	83 c0 40             	add    $0x40,%eax
c0104144:	83 c0 04             	add    $0x4,%eax
c0104147:	c7 45 ac 01 00 00 00 	movl   $0x1,-0x54(%ebp)
c010414e:	89 45 a8             	mov    %eax,-0x58(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0104151:	8b 45 a8             	mov    -0x58(%ebp),%eax
c0104154:	8b 55 ac             	mov    -0x54(%ebp),%edx
c0104157:	0f a3 10             	bt     %edx,(%eax)
c010415a:	19 c0                	sbb    %eax,%eax
c010415c:	89 45 a4             	mov    %eax,-0x5c(%ebp)
    return oldbit != 0;
c010415f:	83 7d a4 00          	cmpl   $0x0,-0x5c(%ebp)
c0104163:	0f 95 c0             	setne  %al
c0104166:	0f b6 c0             	movzbl %al,%eax
c0104169:	85 c0                	test   %eax,%eax
c010416b:	74 0e                	je     c010417b <default_check+0x29c>
c010416d:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104170:	83 c0 40             	add    $0x40,%eax
c0104173:	8b 40 08             	mov    0x8(%eax),%eax
c0104176:	83 f8 03             	cmp    $0x3,%eax
c0104179:	74 24                	je     c010419f <default_check+0x2c0>
c010417b:	c7 44 24 0c d4 ab 10 	movl   $0xc010abd4,0xc(%esp)
c0104182:	c0 
c0104183:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c010418a:	c0 
c010418b:	c7 44 24 04 56 01 00 	movl   $0x156,0x4(%esp)
c0104192:	00 
c0104193:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c010419a:	e8 a6 ca ff ff       	call   c0100c45 <__panic>
    assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面
c010419f:	c7 04 24 03 00 00 00 	movl   $0x3,(%esp)
c01041a6:	e8 30 0e 00 00       	call   c0104fdb <alloc_pages>
c01041ab:	89 45 e0             	mov    %eax,-0x20(%ebp)
c01041ae:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c01041b2:	75 24                	jne    c01041d8 <default_check+0x2f9>
c01041b4:	c7 44 24 0c 00 ac 10 	movl   $0xc010ac00,0xc(%esp)
c01041bb:	c0 
c01041bc:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c01041c3:	c0 
c01041c4:	c7 44 24 04 57 01 00 	movl   $0x157,0x4(%esp)
c01041cb:	00 
c01041cc:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c01041d3:	e8 6d ca ff ff       	call   c0100c45 <__panic>
    assert(alloc_page() == NULL);// 确保没有页面可分配
c01041d8:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01041df:	e8 f7 0d 00 00       	call   c0104fdb <alloc_pages>
c01041e4:	85 c0                	test   %eax,%eax
c01041e6:	74 24                	je     c010420c <default_check+0x32d>
c01041e8:	c7 44 24 0c 16 ab 10 	movl   $0xc010ab16,0xc(%esp)
c01041ef:	c0 
c01041f0:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c01041f7:	c0 
c01041f8:	c7 44 24 04 58 01 00 	movl   $0x158,0x4(%esp)
c01041ff:	00 
c0104200:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0104207:	e8 39 ca ff ff       	call   c0100c45 <__panic>
    assert(p0 + 2 == p1);// 确保分配的页面是释放的页面
c010420c:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010420f:	83 c0 40             	add    $0x40,%eax
c0104212:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c0104215:	74 24                	je     c010423b <default_check+0x35c>
c0104217:	c7 44 24 0c 1e ac 10 	movl   $0xc010ac1e,0xc(%esp)
c010421e:	c0 
c010421f:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0104226:	c0 
c0104227:	c7 44 24 04 59 01 00 	movl   $0x159,0x4(%esp)
c010422e:	00 
c010422f:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0104236:	e8 0a ca ff ff       	call   c0100c45 <__panic>

    p2 = p0 + 1;// 设置 p2 为 p0 的下一个页面
c010423b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010423e:	83 c0 20             	add    $0x20,%eax
c0104241:	89 45 dc             	mov    %eax,-0x24(%ebp)
    free_page(p0);// 释放 p0 页面
c0104244:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c010424b:	00 
c010424c:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010424f:	89 04 24             	mov    %eax,(%esp)
c0104252:	e8 f1 0d 00 00       	call   c0105048 <free_pages>
    free_pages(p1, 3);// 释放 p1 指向的页面
c0104257:	c7 44 24 04 03 00 00 	movl   $0x3,0x4(%esp)
c010425e:	00 
c010425f:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0104262:	89 04 24             	mov    %eax,(%esp)
c0104265:	e8 de 0d 00 00       	call   c0105048 <free_pages>
    assert(PageProperty(p0) && p0->property == 1);// 检查 p0 属性
c010426a:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010426d:	83 c0 04             	add    $0x4,%eax
c0104270:	c7 45 a0 01 00 00 00 	movl   $0x1,-0x60(%ebp)
c0104277:	89 45 9c             	mov    %eax,-0x64(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c010427a:	8b 45 9c             	mov    -0x64(%ebp),%eax
c010427d:	8b 55 a0             	mov    -0x60(%ebp),%edx
c0104280:	0f a3 10             	bt     %edx,(%eax)
c0104283:	19 c0                	sbb    %eax,%eax
c0104285:	89 45 98             	mov    %eax,-0x68(%ebp)
    return oldbit != 0;
c0104288:	83 7d 98 00          	cmpl   $0x0,-0x68(%ebp)
c010428c:	0f 95 c0             	setne  %al
c010428f:	0f b6 c0             	movzbl %al,%eax
c0104292:	85 c0                	test   %eax,%eax
c0104294:	74 0b                	je     c01042a1 <default_check+0x3c2>
c0104296:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104299:	8b 40 08             	mov    0x8(%eax),%eax
c010429c:	83 f8 01             	cmp    $0x1,%eax
c010429f:	74 24                	je     c01042c5 <default_check+0x3e6>
c01042a1:	c7 44 24 0c 2c ac 10 	movl   $0xc010ac2c,0xc(%esp)
c01042a8:	c0 
c01042a9:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c01042b0:	c0 
c01042b1:	c7 44 24 04 5e 01 00 	movl   $0x15e,0x4(%esp)
c01042b8:	00 
c01042b9:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c01042c0:	e8 80 c9 ff ff       	call   c0100c45 <__panic>
    assert(PageProperty(p1) && p1->property == 3);// 检查 p1 属性
c01042c5:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01042c8:	83 c0 04             	add    $0x4,%eax
c01042cb:	c7 45 94 01 00 00 00 	movl   $0x1,-0x6c(%ebp)
c01042d2:	89 45 90             	mov    %eax,-0x70(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c01042d5:	8b 45 90             	mov    -0x70(%ebp),%eax
c01042d8:	8b 55 94             	mov    -0x6c(%ebp),%edx
c01042db:	0f a3 10             	bt     %edx,(%eax)
c01042de:	19 c0                	sbb    %eax,%eax
c01042e0:	89 45 8c             	mov    %eax,-0x74(%ebp)
    return oldbit != 0;
c01042e3:	83 7d 8c 00          	cmpl   $0x0,-0x74(%ebp)
c01042e7:	0f 95 c0             	setne  %al
c01042ea:	0f b6 c0             	movzbl %al,%eax
c01042ed:	85 c0                	test   %eax,%eax
c01042ef:	74 0b                	je     c01042fc <default_check+0x41d>
c01042f1:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01042f4:	8b 40 08             	mov    0x8(%eax),%eax
c01042f7:	83 f8 03             	cmp    $0x3,%eax
c01042fa:	74 24                	je     c0104320 <default_check+0x441>
c01042fc:	c7 44 24 0c 54 ac 10 	movl   $0xc010ac54,0xc(%esp)
c0104303:	c0 
c0104304:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c010430b:	c0 
c010430c:	c7 44 24 04 5f 01 00 	movl   $0x15f,0x4(%esp)
c0104313:	00 
c0104314:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c010431b:	e8 25 c9 ff ff       	call   c0100c45 <__panic>
    // 确保重分配的页面是之前释放的页面
    assert((p0 = alloc_page()) == p2 - 1);
c0104320:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0104327:	e8 af 0c 00 00       	call   c0104fdb <alloc_pages>
c010432c:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010432f:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0104332:	83 e8 20             	sub    $0x20,%eax
c0104335:	39 45 e8             	cmp    %eax,-0x18(%ebp)
c0104338:	74 24                	je     c010435e <default_check+0x47f>
c010433a:	c7 44 24 0c 7a ac 10 	movl   $0xc010ac7a,0xc(%esp)
c0104341:	c0 
c0104342:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0104349:	c0 
c010434a:	c7 44 24 04 61 01 00 	movl   $0x161,0x4(%esp)
c0104351:	00 
c0104352:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0104359:	e8 e7 c8 ff ff       	call   c0100c45 <__panic>
    free_page(p0);// 释放分配的页面
c010435e:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0104365:	00 
c0104366:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104369:	89 04 24             	mov    %eax,(%esp)
c010436c:	e8 d7 0c 00 00       	call   c0105048 <free_pages>
    assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查
c0104371:	c7 04 24 02 00 00 00 	movl   $0x2,(%esp)
c0104378:	e8 5e 0c 00 00       	call   c0104fdb <alloc_pages>
c010437d:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0104380:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0104383:	83 c0 20             	add    $0x20,%eax
c0104386:	39 45 e8             	cmp    %eax,-0x18(%ebp)
c0104389:	74 24                	je     c01043af <default_check+0x4d0>
c010438b:	c7 44 24 0c 98 ac 10 	movl   $0xc010ac98,0xc(%esp)
c0104392:	c0 
c0104393:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c010439a:	c0 
c010439b:	c7 44 24 04 63 01 00 	movl   $0x163,0x4(%esp)
c01043a2:	00 
c01043a3:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c01043aa:	e8 96 c8 ff ff       	call   c0100c45 <__panic>
    // 释放页面并检查空闲状态
    free_pages(p0, 2);
c01043af:	c7 44 24 04 02 00 00 	movl   $0x2,0x4(%esp)
c01043b6:	00 
c01043b7:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01043ba:	89 04 24             	mov    %eax,(%esp)
c01043bd:	e8 86 0c 00 00       	call   c0105048 <free_pages>
    free_page(p2);
c01043c2:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01043c9:	00 
c01043ca:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01043cd:	89 04 24             	mov    %eax,(%esp)
c01043d0:	e8 73 0c 00 00       	call   c0105048 <free_pages>
    // 再次分配 5 个页面
    assert((p0 = alloc_pages(5)) != NULL);
c01043d5:	c7 04 24 05 00 00 00 	movl   $0x5,(%esp)
c01043dc:	e8 fa 0b 00 00       	call   c0104fdb <alloc_pages>
c01043e1:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01043e4:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c01043e8:	75 24                	jne    c010440e <default_check+0x52f>
c01043ea:	c7 44 24 0c b8 ac 10 	movl   $0xc010acb8,0xc(%esp)
c01043f1:	c0 
c01043f2:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c01043f9:	c0 
c01043fa:	c7 44 24 04 68 01 00 	movl   $0x168,0x4(%esp)
c0104401:	00 
c0104402:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0104409:	e8 37 c8 ff ff       	call   c0100c45 <__panic>
    assert(alloc_page() == NULL);// 确保没有额外页面可分配
c010440e:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0104415:	e8 c1 0b 00 00       	call   c0104fdb <alloc_pages>
c010441a:	85 c0                	test   %eax,%eax
c010441c:	74 24                	je     c0104442 <default_check+0x563>
c010441e:	c7 44 24 0c 16 ab 10 	movl   $0xc010ab16,0xc(%esp)
c0104425:	c0 
c0104426:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c010442d:	c0 
c010442e:	c7 44 24 04 69 01 00 	movl   $0x169,0x4(%esp)
c0104435:	00 
c0104436:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c010443d:	e8 03 c8 ff ff       	call   c0100c45 <__panic>

    assert(nr_free == 0);// 确保空闲页数为 0
c0104442:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
c0104447:	85 c0                	test   %eax,%eax
c0104449:	74 24                	je     c010446f <default_check+0x590>
c010444b:	c7 44 24 0c 69 ab 10 	movl   $0xc010ab69,0xc(%esp)
c0104452:	c0 
c0104453:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c010445a:	c0 
c010445b:	c7 44 24 04 6b 01 00 	movl   $0x16b,0x4(%esp)
c0104462:	00 
c0104463:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c010446a:	e8 d6 c7 ff ff       	call   c0100c45 <__panic>
    nr_free = nr_free_store;// 恢复空闲页数
c010446f:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0104472:	a3 ec bf 12 c0       	mov    %eax,0xc012bfec
    // 恢复空闲列表状态
    free_list = free_list_store;
c0104477:	8b 45 80             	mov    -0x80(%ebp),%eax
c010447a:	8b 55 84             	mov    -0x7c(%ebp),%edx
c010447d:	a3 e4 bf 12 c0       	mov    %eax,0xc012bfe4
c0104482:	89 15 e8 bf 12 c0    	mov    %edx,0xc012bfe8
    free_pages(p0, 5);// 释放所有分配的页面
c0104488:	c7 44 24 04 05 00 00 	movl   $0x5,0x4(%esp)
c010448f:	00 
c0104490:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0104493:	89 04 24             	mov    %eax,(%esp)
c0104496:	e8 ad 0b 00 00       	call   c0105048 <free_pages>
    // 验证空闲列表的一致性
    le = &free_list;
c010449b:	c7 45 ec e4 bf 12 c0 	movl   $0xc012bfe4,-0x14(%ebp)
    while ((le = list_next(le)) != &free_list) {
c01044a2:	eb 1c                	jmp    c01044c0 <default_check+0x5e1>
        struct Page *p = le2page(le, page_link);
c01044a4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01044a7:	83 e8 0c             	sub    $0xc,%eax
c01044aa:	89 45 d8             	mov    %eax,-0x28(%ebp)
        count --, total -= p->property;
c01044ad:	ff 4d f4             	decl   -0xc(%ebp)
c01044b0:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01044b3:	8b 45 d8             	mov    -0x28(%ebp),%eax
c01044b6:	8b 48 08             	mov    0x8(%eax),%ecx
c01044b9:	89 d0                	mov    %edx,%eax
c01044bb:	29 c8                	sub    %ecx,%eax
c01044bd:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01044c0:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01044c3:	89 45 88             	mov    %eax,-0x78(%ebp)
    return listelm->next;
c01044c6:	8b 45 88             	mov    -0x78(%ebp),%eax
c01044c9:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(le)) != &free_list) {
c01044cc:	89 45 ec             	mov    %eax,-0x14(%ebp)
c01044cf:	81 7d ec e4 bf 12 c0 	cmpl   $0xc012bfe4,-0x14(%ebp)
c01044d6:	75 cc                	jne    c01044a4 <default_check+0x5c5>
    }
    assert(count == 0);// 确保所有页面都已处理
c01044d8:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01044dc:	74 24                	je     c0104502 <default_check+0x623>
c01044de:	c7 44 24 0c d6 ac 10 	movl   $0xc010acd6,0xc(%esp)
c01044e5:	c0 
c01044e6:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c01044ed:	c0 
c01044ee:	c7 44 24 04 76 01 00 	movl   $0x176,0x4(%esp)
c01044f5:	00 
c01044f6:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c01044fd:	e8 43 c7 ff ff       	call   c0100c45 <__panic>
    assert(total == 0);// 确保总属性值为 0
c0104502:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0104506:	74 24                	je     c010452c <default_check+0x64d>
c0104508:	c7 44 24 0c e1 ac 10 	movl   $0xc010ace1,0xc(%esp)
c010450f:	c0 
c0104510:	c7 44 24 08 76 a9 10 	movl   $0xc010a976,0x8(%esp)
c0104517:	c0 
c0104518:	c7 44 24 04 77 01 00 	movl   $0x177,0x4(%esp)
c010451f:	00 
c0104520:	c7 04 24 8b a9 10 c0 	movl   $0xc010a98b,(%esp)
c0104527:	e8 19 c7 ff ff       	call   c0100c45 <__panic>
}
c010452c:	90                   	nop
c010452d:	89 ec                	mov    %ebp,%esp
c010452f:	5d                   	pop    %ebp
c0104530:	c3                   	ret    

c0104531 <__intr_save>:
__intr_save(void) {
c0104531:	55                   	push   %ebp
c0104532:	89 e5                	mov    %esp,%ebp
c0104534:	83 ec 18             	sub    $0x18,%esp
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c0104537:	9c                   	pushf  
c0104538:	58                   	pop    %eax
c0104539:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c010453c:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c010453f:	25 00 02 00 00       	and    $0x200,%eax
c0104544:	85 c0                	test   %eax,%eax
c0104546:	74 0c                	je     c0104554 <__intr_save+0x23>
        intr_disable();
c0104548:	e8 ae d9 ff ff       	call   c0101efb <intr_disable>
        return 1;
c010454d:	b8 01 00 00 00       	mov    $0x1,%eax
c0104552:	eb 05                	jmp    c0104559 <__intr_save+0x28>
    return 0;
c0104554:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0104559:	89 ec                	mov    %ebp,%esp
c010455b:	5d                   	pop    %ebp
c010455c:	c3                   	ret    

c010455d <__intr_restore>:
__intr_restore(bool flag) {
c010455d:	55                   	push   %ebp
c010455e:	89 e5                	mov    %esp,%ebp
c0104560:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c0104563:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0104567:	74 05                	je     c010456e <__intr_restore+0x11>
        intr_enable();
c0104569:	e8 85 d9 ff ff       	call   c0101ef3 <intr_enable>
}
c010456e:	90                   	nop
c010456f:	89 ec                	mov    %ebp,%esp
c0104571:	5d                   	pop    %ebp
c0104572:	c3                   	ret    

c0104573 <page2ppn>:
page2ppn(struct Page *page) {
c0104573:	55                   	push   %ebp
c0104574:	89 e5                	mov    %esp,%ebp
    return page - pages;
c0104576:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c010457c:	8b 45 08             	mov    0x8(%ebp),%eax
c010457f:	29 d0                	sub    %edx,%eax
c0104581:	c1 f8 05             	sar    $0x5,%eax
}
c0104584:	5d                   	pop    %ebp
c0104585:	c3                   	ret    

c0104586 <page2pa>:
page2pa(struct Page *page) {
c0104586:	55                   	push   %ebp
c0104587:	89 e5                	mov    %esp,%ebp
c0104589:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c010458c:	8b 45 08             	mov    0x8(%ebp),%eax
c010458f:	89 04 24             	mov    %eax,(%esp)
c0104592:	e8 dc ff ff ff       	call   c0104573 <page2ppn>
c0104597:	c1 e0 0c             	shl    $0xc,%eax
}
c010459a:	89 ec                	mov    %ebp,%esp
c010459c:	5d                   	pop    %ebp
c010459d:	c3                   	ret    

c010459e <pa2page>:
pa2page(uintptr_t pa) {
c010459e:	55                   	push   %ebp
c010459f:	89 e5                	mov    %esp,%ebp
c01045a1:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c01045a4:	8b 45 08             	mov    0x8(%ebp),%eax
c01045a7:	c1 e8 0c             	shr    $0xc,%eax
c01045aa:	89 c2                	mov    %eax,%edx
c01045ac:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c01045b1:	39 c2                	cmp    %eax,%edx
c01045b3:	72 1c                	jb     c01045d1 <pa2page+0x33>
        panic("pa2page called with invalid pa");
c01045b5:	c7 44 24 08 1c ad 10 	movl   $0xc010ad1c,0x8(%esp)
c01045bc:	c0 
c01045bd:	c7 44 24 04 5f 00 00 	movl   $0x5f,0x4(%esp)
c01045c4:	00 
c01045c5:	c7 04 24 3b ad 10 c0 	movl   $0xc010ad3b,(%esp)
c01045cc:	e8 74 c6 ff ff       	call   c0100c45 <__panic>
    return &pages[PPN(pa)];
c01045d1:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c01045d7:	8b 45 08             	mov    0x8(%ebp),%eax
c01045da:	c1 e8 0c             	shr    $0xc,%eax
c01045dd:	c1 e0 05             	shl    $0x5,%eax
c01045e0:	01 d0                	add    %edx,%eax
}
c01045e2:	89 ec                	mov    %ebp,%esp
c01045e4:	5d                   	pop    %ebp
c01045e5:	c3                   	ret    

c01045e6 <page2kva>:
page2kva(struct Page *page) {
c01045e6:	55                   	push   %ebp
c01045e7:	89 e5                	mov    %esp,%ebp
c01045e9:	83 ec 28             	sub    $0x28,%esp
    return KADDR(page2pa(page));
c01045ec:	8b 45 08             	mov    0x8(%ebp),%eax
c01045ef:	89 04 24             	mov    %eax,(%esp)
c01045f2:	e8 8f ff ff ff       	call   c0104586 <page2pa>
c01045f7:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01045fa:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01045fd:	c1 e8 0c             	shr    $0xc,%eax
c0104600:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0104603:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c0104608:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c010460b:	72 23                	jb     c0104630 <page2kva+0x4a>
c010460d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104610:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0104614:	c7 44 24 08 4c ad 10 	movl   $0xc010ad4c,0x8(%esp)
c010461b:	c0 
c010461c:	c7 44 24 04 66 00 00 	movl   $0x66,0x4(%esp)
c0104623:	00 
c0104624:	c7 04 24 3b ad 10 c0 	movl   $0xc010ad3b,(%esp)
c010462b:	e8 15 c6 ff ff       	call   c0100c45 <__panic>
c0104630:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104633:	2d 00 00 00 40       	sub    $0x40000000,%eax
}
c0104638:	89 ec                	mov    %ebp,%esp
c010463a:	5d                   	pop    %ebp
c010463b:	c3                   	ret    

c010463c <kva2page>:
kva2page(void *kva) {
c010463c:	55                   	push   %ebp
c010463d:	89 e5                	mov    %esp,%ebp
c010463f:	83 ec 28             	sub    $0x28,%esp
    return pa2page(PADDR(kva));
c0104642:	8b 45 08             	mov    0x8(%ebp),%eax
c0104645:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104648:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c010464f:	77 23                	ja     c0104674 <kva2page+0x38>
c0104651:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104654:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0104658:	c7 44 24 08 70 ad 10 	movl   $0xc010ad70,0x8(%esp)
c010465f:	c0 
c0104660:	c7 44 24 04 6b 00 00 	movl   $0x6b,0x4(%esp)
c0104667:	00 
c0104668:	c7 04 24 3b ad 10 c0 	movl   $0xc010ad3b,(%esp)
c010466f:	e8 d1 c5 ff ff       	call   c0100c45 <__panic>
c0104674:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104677:	05 00 00 00 40       	add    $0x40000000,%eax
c010467c:	89 04 24             	mov    %eax,(%esp)
c010467f:	e8 1a ff ff ff       	call   c010459e <pa2page>
}
c0104684:	89 ec                	mov    %ebp,%esp
c0104686:	5d                   	pop    %ebp
c0104687:	c3                   	ret    

c0104688 <__slob_get_free_pages>:
static slob_t *slobfree = &arena;
static bigblock_t *bigblocks;


static void* __slob_get_free_pages(gfp_t gfp, int order)
{
c0104688:	55                   	push   %ebp
c0104689:	89 e5                	mov    %esp,%ebp
c010468b:	83 ec 28             	sub    $0x28,%esp
  struct Page * page = alloc_pages(1 << order);
c010468e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104691:	ba 01 00 00 00       	mov    $0x1,%edx
c0104696:	88 c1                	mov    %al,%cl
c0104698:	d3 e2                	shl    %cl,%edx
c010469a:	89 d0                	mov    %edx,%eax
c010469c:	89 04 24             	mov    %eax,(%esp)
c010469f:	e8 37 09 00 00       	call   c0104fdb <alloc_pages>
c01046a4:	89 45 f4             	mov    %eax,-0xc(%ebp)
  if(!page)
c01046a7:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01046ab:	75 07                	jne    c01046b4 <__slob_get_free_pages+0x2c>
    return NULL;
c01046ad:	b8 00 00 00 00       	mov    $0x0,%eax
c01046b2:	eb 0b                	jmp    c01046bf <__slob_get_free_pages+0x37>
  return page2kva(page);
c01046b4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01046b7:	89 04 24             	mov    %eax,(%esp)
c01046ba:	e8 27 ff ff ff       	call   c01045e6 <page2kva>
}
c01046bf:	89 ec                	mov    %ebp,%esp
c01046c1:	5d                   	pop    %ebp
c01046c2:	c3                   	ret    

c01046c3 <__slob_free_pages>:

#define __slob_get_free_page(gfp) __slob_get_free_pages(gfp, 0)

static inline void __slob_free_pages(unsigned long kva, int order)
{
c01046c3:	55                   	push   %ebp
c01046c4:	89 e5                	mov    %esp,%ebp
c01046c6:	83 ec 18             	sub    $0x18,%esp
c01046c9:	89 5d fc             	mov    %ebx,-0x4(%ebp)
  free_pages(kva2page(kva), 1 << order);
c01046cc:	8b 45 0c             	mov    0xc(%ebp),%eax
c01046cf:	ba 01 00 00 00       	mov    $0x1,%edx
c01046d4:	88 c1                	mov    %al,%cl
c01046d6:	d3 e2                	shl    %cl,%edx
c01046d8:	89 d0                	mov    %edx,%eax
c01046da:	89 c3                	mov    %eax,%ebx
c01046dc:	8b 45 08             	mov    0x8(%ebp),%eax
c01046df:	89 04 24             	mov    %eax,(%esp)
c01046e2:	e8 55 ff ff ff       	call   c010463c <kva2page>
c01046e7:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c01046eb:	89 04 24             	mov    %eax,(%esp)
c01046ee:	e8 55 09 00 00       	call   c0105048 <free_pages>
}
c01046f3:	90                   	nop
c01046f4:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c01046f7:	89 ec                	mov    %ebp,%esp
c01046f9:	5d                   	pop    %ebp
c01046fa:	c3                   	ret    

c01046fb <slob_alloc>:

static void slob_free(void *b, int size);

static void *slob_alloc(size_t size, gfp_t gfp, int align)
{
c01046fb:	55                   	push   %ebp
c01046fc:	89 e5                	mov    %esp,%ebp
c01046fe:	83 ec 38             	sub    $0x38,%esp
  assert( (size + SLOB_UNIT) < PAGE_SIZE );
c0104701:	8b 45 08             	mov    0x8(%ebp),%eax
c0104704:	83 c0 08             	add    $0x8,%eax
c0104707:	3d ff 0f 00 00       	cmp    $0xfff,%eax
c010470c:	76 24                	jbe    c0104732 <slob_alloc+0x37>
c010470e:	c7 44 24 0c 94 ad 10 	movl   $0xc010ad94,0xc(%esp)
c0104715:	c0 
c0104716:	c7 44 24 08 b3 ad 10 	movl   $0xc010adb3,0x8(%esp)
c010471d:	c0 
c010471e:	c7 44 24 04 64 00 00 	movl   $0x64,0x4(%esp)
c0104725:	00 
c0104726:	c7 04 24 c8 ad 10 c0 	movl   $0xc010adc8,(%esp)
c010472d:	e8 13 c5 ff ff       	call   c0100c45 <__panic>

	slob_t *prev, *cur, *aligned = 0;
c0104732:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
	int delta = 0, units = SLOB_UNITS(size);
c0104739:	c7 45 e8 00 00 00 00 	movl   $0x0,-0x18(%ebp)
c0104740:	8b 45 08             	mov    0x8(%ebp),%eax
c0104743:	83 c0 07             	add    $0x7,%eax
c0104746:	c1 e8 03             	shr    $0x3,%eax
c0104749:	89 45 e0             	mov    %eax,-0x20(%ebp)
	unsigned long flags;

	spin_lock_irqsave(&slob_lock, flags);
c010474c:	e8 e0 fd ff ff       	call   c0104531 <__intr_save>
c0104751:	89 45 e4             	mov    %eax,-0x1c(%ebp)
	prev = slobfree;
c0104754:	a1 e8 89 12 c0       	mov    0xc01289e8,%eax
c0104759:	89 45 f4             	mov    %eax,-0xc(%ebp)
	for (cur = prev->next; ; prev = cur, cur = cur->next) {
c010475c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010475f:	8b 40 04             	mov    0x4(%eax),%eax
c0104762:	89 45 f0             	mov    %eax,-0x10(%ebp)
		if (align) {
c0104765:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0104769:	74 21                	je     c010478c <slob_alloc+0x91>
			aligned = (slob_t *)ALIGN((unsigned long)cur, align);
c010476b:	8b 55 f0             	mov    -0x10(%ebp),%edx
c010476e:	8b 45 10             	mov    0x10(%ebp),%eax
c0104771:	01 d0                	add    %edx,%eax
c0104773:	8d 50 ff             	lea    -0x1(%eax),%edx
c0104776:	8b 45 10             	mov    0x10(%ebp),%eax
c0104779:	f7 d8                	neg    %eax
c010477b:	21 d0                	and    %edx,%eax
c010477d:	89 45 ec             	mov    %eax,-0x14(%ebp)
			delta = aligned - cur;
c0104780:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104783:	2b 45 f0             	sub    -0x10(%ebp),%eax
c0104786:	c1 f8 03             	sar    $0x3,%eax
c0104789:	89 45 e8             	mov    %eax,-0x18(%ebp)
		}
		if (cur->units >= units + delta) { /* room enough? */
c010478c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010478f:	8b 00                	mov    (%eax),%eax
c0104791:	8b 4d e0             	mov    -0x20(%ebp),%ecx
c0104794:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0104797:	01 ca                	add    %ecx,%edx
c0104799:	39 d0                	cmp    %edx,%eax
c010479b:	0f 8c aa 00 00 00    	jl     c010484b <slob_alloc+0x150>
			if (delta) { /* need to fragment head to align? */
c01047a1:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c01047a5:	74 38                	je     c01047df <slob_alloc+0xe4>
				aligned->units = cur->units - delta;
c01047a7:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01047aa:	8b 00                	mov    (%eax),%eax
c01047ac:	2b 45 e8             	sub    -0x18(%ebp),%eax
c01047af:	89 c2                	mov    %eax,%edx
c01047b1:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01047b4:	89 10                	mov    %edx,(%eax)
				aligned->next = cur->next;
c01047b6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01047b9:	8b 50 04             	mov    0x4(%eax),%edx
c01047bc:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01047bf:	89 50 04             	mov    %edx,0x4(%eax)
				cur->next = aligned;
c01047c2:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01047c5:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01047c8:	89 50 04             	mov    %edx,0x4(%eax)
				cur->units = delta;
c01047cb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01047ce:	8b 55 e8             	mov    -0x18(%ebp),%edx
c01047d1:	89 10                	mov    %edx,(%eax)
				prev = cur;
c01047d3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01047d6:	89 45 f4             	mov    %eax,-0xc(%ebp)
				cur = aligned;
c01047d9:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01047dc:	89 45 f0             	mov    %eax,-0x10(%ebp)
			}

			if (cur->units == units) /* exact fit? */
c01047df:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01047e2:	8b 00                	mov    (%eax),%eax
c01047e4:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c01047e7:	75 0e                	jne    c01047f7 <slob_alloc+0xfc>
				prev->next = cur->next; /* unlink */
c01047e9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01047ec:	8b 50 04             	mov    0x4(%eax),%edx
c01047ef:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01047f2:	89 50 04             	mov    %edx,0x4(%eax)
c01047f5:	eb 3c                	jmp    c0104833 <slob_alloc+0x138>
			else { /* fragment */
				prev->next = cur + units;
c01047f7:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01047fa:	8d 14 c5 00 00 00 00 	lea    0x0(,%eax,8),%edx
c0104801:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104804:	01 c2                	add    %eax,%edx
c0104806:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104809:	89 50 04             	mov    %edx,0x4(%eax)
				prev->next->units = cur->units - units;
c010480c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010480f:	8b 10                	mov    (%eax),%edx
c0104811:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104814:	8b 40 04             	mov    0x4(%eax),%eax
c0104817:	2b 55 e0             	sub    -0x20(%ebp),%edx
c010481a:	89 10                	mov    %edx,(%eax)
				prev->next->next = cur->next;
c010481c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010481f:	8b 40 04             	mov    0x4(%eax),%eax
c0104822:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0104825:	8b 52 04             	mov    0x4(%edx),%edx
c0104828:	89 50 04             	mov    %edx,0x4(%eax)
				cur->units = units;
c010482b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010482e:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0104831:	89 10                	mov    %edx,(%eax)
			}

			slobfree = prev;
c0104833:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104836:	a3 e8 89 12 c0       	mov    %eax,0xc01289e8
			spin_unlock_irqrestore(&slob_lock, flags);
c010483b:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010483e:	89 04 24             	mov    %eax,(%esp)
c0104841:	e8 17 fd ff ff       	call   c010455d <__intr_restore>
			return cur;
c0104846:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104849:	eb 7f                	jmp    c01048ca <slob_alloc+0x1cf>
		}
		if (cur == slobfree) {
c010484b:	a1 e8 89 12 c0       	mov    0xc01289e8,%eax
c0104850:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0104853:	75 61                	jne    c01048b6 <slob_alloc+0x1bb>
			spin_unlock_irqrestore(&slob_lock, flags);
c0104855:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0104858:	89 04 24             	mov    %eax,(%esp)
c010485b:	e8 fd fc ff ff       	call   c010455d <__intr_restore>

			if (size == PAGE_SIZE) /* trying to shrink arena? */
c0104860:	81 7d 08 00 10 00 00 	cmpl   $0x1000,0x8(%ebp)
c0104867:	75 07                	jne    c0104870 <slob_alloc+0x175>
				return 0;
c0104869:	b8 00 00 00 00       	mov    $0x0,%eax
c010486e:	eb 5a                	jmp    c01048ca <slob_alloc+0x1cf>

			cur = (slob_t *)__slob_get_free_page(gfp);
c0104870:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0104877:	00 
c0104878:	8b 45 0c             	mov    0xc(%ebp),%eax
c010487b:	89 04 24             	mov    %eax,(%esp)
c010487e:	e8 05 fe ff ff       	call   c0104688 <__slob_get_free_pages>
c0104883:	89 45 f0             	mov    %eax,-0x10(%ebp)
			if (!cur)
c0104886:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010488a:	75 07                	jne    c0104893 <slob_alloc+0x198>
				return 0;
c010488c:	b8 00 00 00 00       	mov    $0x0,%eax
c0104891:	eb 37                	jmp    c01048ca <slob_alloc+0x1cf>

			slob_free(cur, PAGE_SIZE);
c0104893:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c010489a:	00 
c010489b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010489e:	89 04 24             	mov    %eax,(%esp)
c01048a1:	e8 28 00 00 00       	call   c01048ce <slob_free>
			spin_lock_irqsave(&slob_lock, flags);
c01048a6:	e8 86 fc ff ff       	call   c0104531 <__intr_save>
c01048ab:	89 45 e4             	mov    %eax,-0x1c(%ebp)
			cur = slobfree;
c01048ae:	a1 e8 89 12 c0       	mov    0xc01289e8,%eax
c01048b3:	89 45 f0             	mov    %eax,-0x10(%ebp)
	for (cur = prev->next; ; prev = cur, cur = cur->next) {
c01048b6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01048b9:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01048bc:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01048bf:	8b 40 04             	mov    0x4(%eax),%eax
c01048c2:	89 45 f0             	mov    %eax,-0x10(%ebp)
		if (align) {
c01048c5:	e9 9b fe ff ff       	jmp    c0104765 <slob_alloc+0x6a>
		}
	}
}
c01048ca:	89 ec                	mov    %ebp,%esp
c01048cc:	5d                   	pop    %ebp
c01048cd:	c3                   	ret    

c01048ce <slob_free>:

static void slob_free(void *block, int size)
{
c01048ce:	55                   	push   %ebp
c01048cf:	89 e5                	mov    %esp,%ebp
c01048d1:	83 ec 28             	sub    $0x28,%esp
	slob_t *cur, *b = (slob_t *)block;
c01048d4:	8b 45 08             	mov    0x8(%ebp),%eax
c01048d7:	89 45 f0             	mov    %eax,-0x10(%ebp)
	unsigned long flags;

	if (!block)
c01048da:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c01048de:	0f 84 01 01 00 00    	je     c01049e5 <slob_free+0x117>
		return;

	if (size)
c01048e4:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c01048e8:	74 10                	je     c01048fa <slob_free+0x2c>
		b->units = SLOB_UNITS(size);
c01048ea:	8b 45 0c             	mov    0xc(%ebp),%eax
c01048ed:	83 c0 07             	add    $0x7,%eax
c01048f0:	c1 e8 03             	shr    $0x3,%eax
c01048f3:	89 c2                	mov    %eax,%edx
c01048f5:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01048f8:	89 10                	mov    %edx,(%eax)

	/* Find reinsertion point */
	spin_lock_irqsave(&slob_lock, flags);
c01048fa:	e8 32 fc ff ff       	call   c0104531 <__intr_save>
c01048ff:	89 45 ec             	mov    %eax,-0x14(%ebp)
	for (cur = slobfree; !(b > cur && b < cur->next); cur = cur->next)
c0104902:	a1 e8 89 12 c0       	mov    0xc01289e8,%eax
c0104907:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010490a:	eb 27                	jmp    c0104933 <slob_free+0x65>
		if (cur >= cur->next && (b > cur || b < cur->next))
c010490c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010490f:	8b 40 04             	mov    0x4(%eax),%eax
c0104912:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0104915:	72 13                	jb     c010492a <slob_free+0x5c>
c0104917:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010491a:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c010491d:	77 27                	ja     c0104946 <slob_free+0x78>
c010491f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104922:	8b 40 04             	mov    0x4(%eax),%eax
c0104925:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0104928:	72 1c                	jb     c0104946 <slob_free+0x78>
	for (cur = slobfree; !(b > cur && b < cur->next); cur = cur->next)
c010492a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010492d:	8b 40 04             	mov    0x4(%eax),%eax
c0104930:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104933:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104936:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0104939:	76 d1                	jbe    c010490c <slob_free+0x3e>
c010493b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010493e:	8b 40 04             	mov    0x4(%eax),%eax
c0104941:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0104944:	73 c6                	jae    c010490c <slob_free+0x3e>
			break;

	if (b + b->units == cur->next) {
c0104946:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104949:	8b 00                	mov    (%eax),%eax
c010494b:	8d 14 c5 00 00 00 00 	lea    0x0(,%eax,8),%edx
c0104952:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104955:	01 c2                	add    %eax,%edx
c0104957:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010495a:	8b 40 04             	mov    0x4(%eax),%eax
c010495d:	39 c2                	cmp    %eax,%edx
c010495f:	75 25                	jne    c0104986 <slob_free+0xb8>
		b->units += cur->next->units;
c0104961:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104964:	8b 10                	mov    (%eax),%edx
c0104966:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104969:	8b 40 04             	mov    0x4(%eax),%eax
c010496c:	8b 00                	mov    (%eax),%eax
c010496e:	01 c2                	add    %eax,%edx
c0104970:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104973:	89 10                	mov    %edx,(%eax)
		b->next = cur->next->next;
c0104975:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104978:	8b 40 04             	mov    0x4(%eax),%eax
c010497b:	8b 50 04             	mov    0x4(%eax),%edx
c010497e:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104981:	89 50 04             	mov    %edx,0x4(%eax)
c0104984:	eb 0c                	jmp    c0104992 <slob_free+0xc4>
	} else
		b->next = cur->next;
c0104986:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104989:	8b 50 04             	mov    0x4(%eax),%edx
c010498c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010498f:	89 50 04             	mov    %edx,0x4(%eax)

	if (cur + cur->units == b) {
c0104992:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104995:	8b 00                	mov    (%eax),%eax
c0104997:	8d 14 c5 00 00 00 00 	lea    0x0(,%eax,8),%edx
c010499e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01049a1:	01 d0                	add    %edx,%eax
c01049a3:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c01049a6:	75 1f                	jne    c01049c7 <slob_free+0xf9>
		cur->units += b->units;
c01049a8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01049ab:	8b 10                	mov    (%eax),%edx
c01049ad:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01049b0:	8b 00                	mov    (%eax),%eax
c01049b2:	01 c2                	add    %eax,%edx
c01049b4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01049b7:	89 10                	mov    %edx,(%eax)
		cur->next = b->next;
c01049b9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01049bc:	8b 50 04             	mov    0x4(%eax),%edx
c01049bf:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01049c2:	89 50 04             	mov    %edx,0x4(%eax)
c01049c5:	eb 09                	jmp    c01049d0 <slob_free+0x102>
	} else
		cur->next = b;
c01049c7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01049ca:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01049cd:	89 50 04             	mov    %edx,0x4(%eax)

	slobfree = cur;
c01049d0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01049d3:	a3 e8 89 12 c0       	mov    %eax,0xc01289e8

	spin_unlock_irqrestore(&slob_lock, flags);
c01049d8:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01049db:	89 04 24             	mov    %eax,(%esp)
c01049de:	e8 7a fb ff ff       	call   c010455d <__intr_restore>
c01049e3:	eb 01                	jmp    c01049e6 <slob_free+0x118>
		return;
c01049e5:	90                   	nop
}
c01049e6:	89 ec                	mov    %ebp,%esp
c01049e8:	5d                   	pop    %ebp
c01049e9:	c3                   	ret    

c01049ea <slob_init>:



void
slob_init(void) {
c01049ea:	55                   	push   %ebp
c01049eb:	89 e5                	mov    %esp,%ebp
c01049ed:	83 ec 18             	sub    $0x18,%esp
  cprintf("use SLOB allocator\n");
c01049f0:	c7 04 24 da ad 10 c0 	movl   $0xc010adda,(%esp)
c01049f7:	e8 7c b9 ff ff       	call   c0100378 <cprintf>
}
c01049fc:	90                   	nop
c01049fd:	89 ec                	mov    %ebp,%esp
c01049ff:	5d                   	pop    %ebp
c0104a00:	c3                   	ret    

c0104a01 <kmalloc_init>:

inline void 
kmalloc_init(void) {
c0104a01:	55                   	push   %ebp
c0104a02:	89 e5                	mov    %esp,%ebp
c0104a04:	83 ec 18             	sub    $0x18,%esp
    slob_init();
c0104a07:	e8 de ff ff ff       	call   c01049ea <slob_init>
    cprintf("kmalloc_init() succeeded!\n");
c0104a0c:	c7 04 24 ee ad 10 c0 	movl   $0xc010adee,(%esp)
c0104a13:	e8 60 b9 ff ff       	call   c0100378 <cprintf>
}
c0104a18:	90                   	nop
c0104a19:	89 ec                	mov    %ebp,%esp
c0104a1b:	5d                   	pop    %ebp
c0104a1c:	c3                   	ret    

c0104a1d <slob_allocated>:

size_t
slob_allocated(void) {
c0104a1d:	55                   	push   %ebp
c0104a1e:	89 e5                	mov    %esp,%ebp
  return 0;
c0104a20:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0104a25:	5d                   	pop    %ebp
c0104a26:	c3                   	ret    

c0104a27 <kallocated>:

size_t
kallocated(void) {
c0104a27:	55                   	push   %ebp
c0104a28:	89 e5                	mov    %esp,%ebp
   return slob_allocated();
c0104a2a:	e8 ee ff ff ff       	call   c0104a1d <slob_allocated>
}
c0104a2f:	5d                   	pop    %ebp
c0104a30:	c3                   	ret    

c0104a31 <find_order>:

static int find_order(int size)
{
c0104a31:	55                   	push   %ebp
c0104a32:	89 e5                	mov    %esp,%ebp
c0104a34:	83 ec 10             	sub    $0x10,%esp
	int order = 0;
c0104a37:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
	for ( ; size > 4096 ; size >>=1)
c0104a3e:	eb 06                	jmp    c0104a46 <find_order+0x15>
		order++;
c0104a40:	ff 45 fc             	incl   -0x4(%ebp)
	for ( ; size > 4096 ; size >>=1)
c0104a43:	d1 7d 08             	sarl   0x8(%ebp)
c0104a46:	81 7d 08 00 10 00 00 	cmpl   $0x1000,0x8(%ebp)
c0104a4d:	7f f1                	jg     c0104a40 <find_order+0xf>
	return order;
c0104a4f:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c0104a52:	89 ec                	mov    %ebp,%esp
c0104a54:	5d                   	pop    %ebp
c0104a55:	c3                   	ret    

c0104a56 <__kmalloc>:

static void *__kmalloc(size_t size, gfp_t gfp)
{
c0104a56:	55                   	push   %ebp
c0104a57:	89 e5                	mov    %esp,%ebp
c0104a59:	83 ec 28             	sub    $0x28,%esp
	slob_t *m;
	bigblock_t *bb;
	unsigned long flags;

	if (size < PAGE_SIZE - SLOB_UNIT) {
c0104a5c:	81 7d 08 f7 0f 00 00 	cmpl   $0xff7,0x8(%ebp)
c0104a63:	77 3b                	ja     c0104aa0 <__kmalloc+0x4a>
		m = slob_alloc(size + SLOB_UNIT, gfp, 0);
c0104a65:	8b 45 08             	mov    0x8(%ebp),%eax
c0104a68:	8d 50 08             	lea    0x8(%eax),%edx
c0104a6b:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0104a72:	00 
c0104a73:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104a76:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104a7a:	89 14 24             	mov    %edx,(%esp)
c0104a7d:	e8 79 fc ff ff       	call   c01046fb <slob_alloc>
c0104a82:	89 45 ec             	mov    %eax,-0x14(%ebp)
		return m ? (void *)(m + 1) : 0;
c0104a85:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0104a89:	74 0b                	je     c0104a96 <__kmalloc+0x40>
c0104a8b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104a8e:	83 c0 08             	add    $0x8,%eax
c0104a91:	e9 b0 00 00 00       	jmp    c0104b46 <__kmalloc+0xf0>
c0104a96:	b8 00 00 00 00       	mov    $0x0,%eax
c0104a9b:	e9 a6 00 00 00       	jmp    c0104b46 <__kmalloc+0xf0>
	}

	bb = slob_alloc(sizeof(bigblock_t), gfp, 0);
c0104aa0:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0104aa7:	00 
c0104aa8:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104aab:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104aaf:	c7 04 24 0c 00 00 00 	movl   $0xc,(%esp)
c0104ab6:	e8 40 fc ff ff       	call   c01046fb <slob_alloc>
c0104abb:	89 45 f4             	mov    %eax,-0xc(%ebp)
	if (!bb)
c0104abe:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0104ac2:	75 07                	jne    c0104acb <__kmalloc+0x75>
		return 0;
c0104ac4:	b8 00 00 00 00       	mov    $0x0,%eax
c0104ac9:	eb 7b                	jmp    c0104b46 <__kmalloc+0xf0>

	bb->order = find_order(size);
c0104acb:	8b 45 08             	mov    0x8(%ebp),%eax
c0104ace:	89 04 24             	mov    %eax,(%esp)
c0104ad1:	e8 5b ff ff ff       	call   c0104a31 <find_order>
c0104ad6:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0104ad9:	89 02                	mov    %eax,(%edx)
	bb->pages = (void *)__slob_get_free_pages(gfp, bb->order);
c0104adb:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104ade:	8b 00                	mov    (%eax),%eax
c0104ae0:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104ae4:	8b 45 0c             	mov    0xc(%ebp),%eax
c0104ae7:	89 04 24             	mov    %eax,(%esp)
c0104aea:	e8 99 fb ff ff       	call   c0104688 <__slob_get_free_pages>
c0104aef:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0104af2:	89 42 04             	mov    %eax,0x4(%edx)

	if (bb->pages) {
c0104af5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104af8:	8b 40 04             	mov    0x4(%eax),%eax
c0104afb:	85 c0                	test   %eax,%eax
c0104afd:	74 2f                	je     c0104b2e <__kmalloc+0xd8>
		spin_lock_irqsave(&block_lock, flags);
c0104aff:	e8 2d fa ff ff       	call   c0104531 <__intr_save>
c0104b04:	89 45 f0             	mov    %eax,-0x10(%ebp)
		bb->next = bigblocks;
c0104b07:	8b 15 f0 bf 12 c0    	mov    0xc012bff0,%edx
c0104b0d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b10:	89 50 08             	mov    %edx,0x8(%eax)
		bigblocks = bb;
c0104b13:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b16:	a3 f0 bf 12 c0       	mov    %eax,0xc012bff0
		spin_unlock_irqrestore(&block_lock, flags);
c0104b1b:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104b1e:	89 04 24             	mov    %eax,(%esp)
c0104b21:	e8 37 fa ff ff       	call   c010455d <__intr_restore>
		return bb->pages;
c0104b26:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b29:	8b 40 04             	mov    0x4(%eax),%eax
c0104b2c:	eb 18                	jmp    c0104b46 <__kmalloc+0xf0>
	}

	slob_free(bb, sizeof(bigblock_t));
c0104b2e:	c7 44 24 04 0c 00 00 	movl   $0xc,0x4(%esp)
c0104b35:	00 
c0104b36:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b39:	89 04 24             	mov    %eax,(%esp)
c0104b3c:	e8 8d fd ff ff       	call   c01048ce <slob_free>
	return 0;
c0104b41:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0104b46:	89 ec                	mov    %ebp,%esp
c0104b48:	5d                   	pop    %ebp
c0104b49:	c3                   	ret    

c0104b4a <kmalloc>:

void *
kmalloc(size_t size)
{
c0104b4a:	55                   	push   %ebp
c0104b4b:	89 e5                	mov    %esp,%ebp
c0104b4d:	83 ec 18             	sub    $0x18,%esp
  return __kmalloc(size, 0);
c0104b50:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0104b57:	00 
c0104b58:	8b 45 08             	mov    0x8(%ebp),%eax
c0104b5b:	89 04 24             	mov    %eax,(%esp)
c0104b5e:	e8 f3 fe ff ff       	call   c0104a56 <__kmalloc>
}
c0104b63:	89 ec                	mov    %ebp,%esp
c0104b65:	5d                   	pop    %ebp
c0104b66:	c3                   	ret    

c0104b67 <kfree>:


void kfree(void *block)
{
c0104b67:	55                   	push   %ebp
c0104b68:	89 e5                	mov    %esp,%ebp
c0104b6a:	83 ec 28             	sub    $0x28,%esp
	bigblock_t *bb, **last = &bigblocks;
c0104b6d:	c7 45 f0 f0 bf 12 c0 	movl   $0xc012bff0,-0x10(%ebp)
	unsigned long flags;

	if (!block)
c0104b74:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0104b78:	0f 84 a3 00 00 00    	je     c0104c21 <kfree+0xba>
		return;

	if (!((unsigned long)block & (PAGE_SIZE-1))) {
c0104b7e:	8b 45 08             	mov    0x8(%ebp),%eax
c0104b81:	25 ff 0f 00 00       	and    $0xfff,%eax
c0104b86:	85 c0                	test   %eax,%eax
c0104b88:	75 7f                	jne    c0104c09 <kfree+0xa2>
		/* might be on the big block list */
		spin_lock_irqsave(&block_lock, flags);
c0104b8a:	e8 a2 f9 ff ff       	call   c0104531 <__intr_save>
c0104b8f:	89 45 ec             	mov    %eax,-0x14(%ebp)
		for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) {
c0104b92:	a1 f0 bf 12 c0       	mov    0xc012bff0,%eax
c0104b97:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104b9a:	eb 5c                	jmp    c0104bf8 <kfree+0x91>
			if (bb->pages == block) {
c0104b9c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104b9f:	8b 40 04             	mov    0x4(%eax),%eax
c0104ba2:	39 45 08             	cmp    %eax,0x8(%ebp)
c0104ba5:	75 3f                	jne    c0104be6 <kfree+0x7f>
				*last = bb->next;
c0104ba7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104baa:	8b 50 08             	mov    0x8(%eax),%edx
c0104bad:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104bb0:	89 10                	mov    %edx,(%eax)
				spin_unlock_irqrestore(&block_lock, flags);
c0104bb2:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104bb5:	89 04 24             	mov    %eax,(%esp)
c0104bb8:	e8 a0 f9 ff ff       	call   c010455d <__intr_restore>
				__slob_free_pages((unsigned long)block, bb->order);
c0104bbd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104bc0:	8b 10                	mov    (%eax),%edx
c0104bc2:	8b 45 08             	mov    0x8(%ebp),%eax
c0104bc5:	89 54 24 04          	mov    %edx,0x4(%esp)
c0104bc9:	89 04 24             	mov    %eax,(%esp)
c0104bcc:	e8 f2 fa ff ff       	call   c01046c3 <__slob_free_pages>
				slob_free(bb, sizeof(bigblock_t));
c0104bd1:	c7 44 24 04 0c 00 00 	movl   $0xc,0x4(%esp)
c0104bd8:	00 
c0104bd9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104bdc:	89 04 24             	mov    %eax,(%esp)
c0104bdf:	e8 ea fc ff ff       	call   c01048ce <slob_free>
				return;
c0104be4:	eb 3c                	jmp    c0104c22 <kfree+0xbb>
		for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) {
c0104be6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104be9:	83 c0 08             	add    $0x8,%eax
c0104bec:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0104bef:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104bf2:	8b 40 08             	mov    0x8(%eax),%eax
c0104bf5:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104bf8:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0104bfc:	75 9e                	jne    c0104b9c <kfree+0x35>
			}
		}
		spin_unlock_irqrestore(&block_lock, flags);
c0104bfe:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0104c01:	89 04 24             	mov    %eax,(%esp)
c0104c04:	e8 54 f9 ff ff       	call   c010455d <__intr_restore>
	}

	slob_free((slob_t *)block - 1, 0);
c0104c09:	8b 45 08             	mov    0x8(%ebp),%eax
c0104c0c:	83 e8 08             	sub    $0x8,%eax
c0104c0f:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0104c16:	00 
c0104c17:	89 04 24             	mov    %eax,(%esp)
c0104c1a:	e8 af fc ff ff       	call   c01048ce <slob_free>
	return;
c0104c1f:	eb 01                	jmp    c0104c22 <kfree+0xbb>
		return;
c0104c21:	90                   	nop
}
c0104c22:	89 ec                	mov    %ebp,%esp
c0104c24:	5d                   	pop    %ebp
c0104c25:	c3                   	ret    

c0104c26 <ksize>:


unsigned int ksize(const void *block)
{
c0104c26:	55                   	push   %ebp
c0104c27:	89 e5                	mov    %esp,%ebp
c0104c29:	83 ec 28             	sub    $0x28,%esp
	bigblock_t *bb;
	unsigned long flags;

	if (!block)
c0104c2c:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0104c30:	75 07                	jne    c0104c39 <ksize+0x13>
		return 0;
c0104c32:	b8 00 00 00 00       	mov    $0x0,%eax
c0104c37:	eb 6b                	jmp    c0104ca4 <ksize+0x7e>

	if (!((unsigned long)block & (PAGE_SIZE-1))) {
c0104c39:	8b 45 08             	mov    0x8(%ebp),%eax
c0104c3c:	25 ff 0f 00 00       	and    $0xfff,%eax
c0104c41:	85 c0                	test   %eax,%eax
c0104c43:	75 54                	jne    c0104c99 <ksize+0x73>
		spin_lock_irqsave(&block_lock, flags);
c0104c45:	e8 e7 f8 ff ff       	call   c0104531 <__intr_save>
c0104c4a:	89 45 f0             	mov    %eax,-0x10(%ebp)
		for (bb = bigblocks; bb; bb = bb->next)
c0104c4d:	a1 f0 bf 12 c0       	mov    0xc012bff0,%eax
c0104c52:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104c55:	eb 31                	jmp    c0104c88 <ksize+0x62>
			if (bb->pages == block) {
c0104c57:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104c5a:	8b 40 04             	mov    0x4(%eax),%eax
c0104c5d:	39 45 08             	cmp    %eax,0x8(%ebp)
c0104c60:	75 1d                	jne    c0104c7f <ksize+0x59>
				spin_unlock_irqrestore(&slob_lock, flags);
c0104c62:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104c65:	89 04 24             	mov    %eax,(%esp)
c0104c68:	e8 f0 f8 ff ff       	call   c010455d <__intr_restore>
				return PAGE_SIZE << bb->order;
c0104c6d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104c70:	8b 00                	mov    (%eax),%eax
c0104c72:	ba 00 10 00 00       	mov    $0x1000,%edx
c0104c77:	88 c1                	mov    %al,%cl
c0104c79:	d3 e2                	shl    %cl,%edx
c0104c7b:	89 d0                	mov    %edx,%eax
c0104c7d:	eb 25                	jmp    c0104ca4 <ksize+0x7e>
		for (bb = bigblocks; bb; bb = bb->next)
c0104c7f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104c82:	8b 40 08             	mov    0x8(%eax),%eax
c0104c85:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104c88:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0104c8c:	75 c9                	jne    c0104c57 <ksize+0x31>
			}
		spin_unlock_irqrestore(&block_lock, flags);
c0104c8e:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0104c91:	89 04 24             	mov    %eax,(%esp)
c0104c94:	e8 c4 f8 ff ff       	call   c010455d <__intr_restore>
	}

	return ((slob_t *)block - 1)->units * SLOB_UNIT;
c0104c99:	8b 45 08             	mov    0x8(%ebp),%eax
c0104c9c:	83 e8 08             	sub    $0x8,%eax
c0104c9f:	8b 00                	mov    (%eax),%eax
c0104ca1:	c1 e0 03             	shl    $0x3,%eax
}
c0104ca4:	89 ec                	mov    %ebp,%esp
c0104ca6:	5d                   	pop    %ebp
c0104ca7:	c3                   	ret    

c0104ca8 <page2ppn>:
page2ppn(struct Page *page) {
c0104ca8:	55                   	push   %ebp
c0104ca9:	89 e5                	mov    %esp,%ebp
    return page - pages;
c0104cab:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c0104cb1:	8b 45 08             	mov    0x8(%ebp),%eax
c0104cb4:	29 d0                	sub    %edx,%eax
c0104cb6:	c1 f8 05             	sar    $0x5,%eax
}
c0104cb9:	5d                   	pop    %ebp
c0104cba:	c3                   	ret    

c0104cbb <page2pa>:
page2pa(struct Page *page) {
c0104cbb:	55                   	push   %ebp
c0104cbc:	89 e5                	mov    %esp,%ebp
c0104cbe:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c0104cc1:	8b 45 08             	mov    0x8(%ebp),%eax
c0104cc4:	89 04 24             	mov    %eax,(%esp)
c0104cc7:	e8 dc ff ff ff       	call   c0104ca8 <page2ppn>
c0104ccc:	c1 e0 0c             	shl    $0xc,%eax
}
c0104ccf:	89 ec                	mov    %ebp,%esp
c0104cd1:	5d                   	pop    %ebp
c0104cd2:	c3                   	ret    

c0104cd3 <pa2page>:
pa2page(uintptr_t pa) {
c0104cd3:	55                   	push   %ebp
c0104cd4:	89 e5                	mov    %esp,%ebp
c0104cd6:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c0104cd9:	8b 45 08             	mov    0x8(%ebp),%eax
c0104cdc:	c1 e8 0c             	shr    $0xc,%eax
c0104cdf:	89 c2                	mov    %eax,%edx
c0104ce1:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c0104ce6:	39 c2                	cmp    %eax,%edx
c0104ce8:	72 1c                	jb     c0104d06 <pa2page+0x33>
        panic("pa2page called with invalid pa");
c0104cea:	c7 44 24 08 0c ae 10 	movl   $0xc010ae0c,0x8(%esp)
c0104cf1:	c0 
c0104cf2:	c7 44 24 04 5f 00 00 	movl   $0x5f,0x4(%esp)
c0104cf9:	00 
c0104cfa:	c7 04 24 2b ae 10 c0 	movl   $0xc010ae2b,(%esp)
c0104d01:	e8 3f bf ff ff       	call   c0100c45 <__panic>
    return &pages[PPN(pa)];
c0104d06:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c0104d0c:	8b 45 08             	mov    0x8(%ebp),%eax
c0104d0f:	c1 e8 0c             	shr    $0xc,%eax
c0104d12:	c1 e0 05             	shl    $0x5,%eax
c0104d15:	01 d0                	add    %edx,%eax
}
c0104d17:	89 ec                	mov    %ebp,%esp
c0104d19:	5d                   	pop    %ebp
c0104d1a:	c3                   	ret    

c0104d1b <page2kva>:
page2kva(struct Page *page) {
c0104d1b:	55                   	push   %ebp
c0104d1c:	89 e5                	mov    %esp,%ebp
c0104d1e:	83 ec 28             	sub    $0x28,%esp
    return KADDR(page2pa(page));
c0104d21:	8b 45 08             	mov    0x8(%ebp),%eax
c0104d24:	89 04 24             	mov    %eax,(%esp)
c0104d27:	e8 8f ff ff ff       	call   c0104cbb <page2pa>
c0104d2c:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0104d2f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104d32:	c1 e8 0c             	shr    $0xc,%eax
c0104d35:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0104d38:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c0104d3d:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0104d40:	72 23                	jb     c0104d65 <page2kva+0x4a>
c0104d42:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104d45:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0104d49:	c7 44 24 08 3c ae 10 	movl   $0xc010ae3c,0x8(%esp)
c0104d50:	c0 
c0104d51:	c7 44 24 04 66 00 00 	movl   $0x66,0x4(%esp)
c0104d58:	00 
c0104d59:	c7 04 24 2b ae 10 c0 	movl   $0xc010ae2b,(%esp)
c0104d60:	e8 e0 be ff ff       	call   c0100c45 <__panic>
c0104d65:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0104d68:	2d 00 00 00 40       	sub    $0x40000000,%eax
}
c0104d6d:	89 ec                	mov    %ebp,%esp
c0104d6f:	5d                   	pop    %ebp
c0104d70:	c3                   	ret    

c0104d71 <pte2page>:
pte2page(pte_t pte) {
c0104d71:	55                   	push   %ebp
c0104d72:	89 e5                	mov    %esp,%ebp
c0104d74:	83 ec 18             	sub    $0x18,%esp
    if (!(pte & PTE_P)) {
c0104d77:	8b 45 08             	mov    0x8(%ebp),%eax
c0104d7a:	83 e0 01             	and    $0x1,%eax
c0104d7d:	85 c0                	test   %eax,%eax
c0104d7f:	75 1c                	jne    c0104d9d <pte2page+0x2c>
        panic("pte2page called with invalid pte");
c0104d81:	c7 44 24 08 60 ae 10 	movl   $0xc010ae60,0x8(%esp)
c0104d88:	c0 
c0104d89:	c7 44 24 04 71 00 00 	movl   $0x71,0x4(%esp)
c0104d90:	00 
c0104d91:	c7 04 24 2b ae 10 c0 	movl   $0xc010ae2b,(%esp)
c0104d98:	e8 a8 be ff ff       	call   c0100c45 <__panic>
    return pa2page(PTE_ADDR(pte));
c0104d9d:	8b 45 08             	mov    0x8(%ebp),%eax
c0104da0:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0104da5:	89 04 24             	mov    %eax,(%esp)
c0104da8:	e8 26 ff ff ff       	call   c0104cd3 <pa2page>
}
c0104dad:	89 ec                	mov    %ebp,%esp
c0104daf:	5d                   	pop    %ebp
c0104db0:	c3                   	ret    

c0104db1 <pde2page>:
pde2page(pde_t pde) {
c0104db1:	55                   	push   %ebp
c0104db2:	89 e5                	mov    %esp,%ebp
c0104db4:	83 ec 18             	sub    $0x18,%esp
    return pa2page(PDE_ADDR(pde));
c0104db7:	8b 45 08             	mov    0x8(%ebp),%eax
c0104dba:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0104dbf:	89 04 24             	mov    %eax,(%esp)
c0104dc2:	e8 0c ff ff ff       	call   c0104cd3 <pa2page>
}
c0104dc7:	89 ec                	mov    %ebp,%esp
c0104dc9:	5d                   	pop    %ebp
c0104dca:	c3                   	ret    

c0104dcb <page_ref>:
page_ref(struct Page *page) {
c0104dcb:	55                   	push   %ebp
c0104dcc:	89 e5                	mov    %esp,%ebp
    return page->ref;
c0104dce:	8b 45 08             	mov    0x8(%ebp),%eax
c0104dd1:	8b 00                	mov    (%eax),%eax
}
c0104dd3:	5d                   	pop    %ebp
c0104dd4:	c3                   	ret    

c0104dd5 <set_page_ref>:
set_page_ref(struct Page *page, int val) {
c0104dd5:	55                   	push   %ebp
c0104dd6:	89 e5                	mov    %esp,%ebp
    page->ref = val;
c0104dd8:	8b 45 08             	mov    0x8(%ebp),%eax
c0104ddb:	8b 55 0c             	mov    0xc(%ebp),%edx
c0104dde:	89 10                	mov    %edx,(%eax)
}
c0104de0:	90                   	nop
c0104de1:	5d                   	pop    %ebp
c0104de2:	c3                   	ret    

c0104de3 <page_ref_inc>:

static inline int
page_ref_inc(struct Page *page) {
c0104de3:	55                   	push   %ebp
c0104de4:	89 e5                	mov    %esp,%ebp
    page->ref += 1;
c0104de6:	8b 45 08             	mov    0x8(%ebp),%eax
c0104de9:	8b 00                	mov    (%eax),%eax
c0104deb:	8d 50 01             	lea    0x1(%eax),%edx
c0104dee:	8b 45 08             	mov    0x8(%ebp),%eax
c0104df1:	89 10                	mov    %edx,(%eax)
    return page->ref;
c0104df3:	8b 45 08             	mov    0x8(%ebp),%eax
c0104df6:	8b 00                	mov    (%eax),%eax
}
c0104df8:	5d                   	pop    %ebp
c0104df9:	c3                   	ret    

c0104dfa <page_ref_dec>:

static inline int
page_ref_dec(struct Page *page) {
c0104dfa:	55                   	push   %ebp
c0104dfb:	89 e5                	mov    %esp,%ebp
    page->ref -= 1;
c0104dfd:	8b 45 08             	mov    0x8(%ebp),%eax
c0104e00:	8b 00                	mov    (%eax),%eax
c0104e02:	8d 50 ff             	lea    -0x1(%eax),%edx
c0104e05:	8b 45 08             	mov    0x8(%ebp),%eax
c0104e08:	89 10                	mov    %edx,(%eax)
    return page->ref;
c0104e0a:	8b 45 08             	mov    0x8(%ebp),%eax
c0104e0d:	8b 00                	mov    (%eax),%eax
}
c0104e0f:	5d                   	pop    %ebp
c0104e10:	c3                   	ret    

c0104e11 <__intr_save>:
__intr_save(void) {
c0104e11:	55                   	push   %ebp
c0104e12:	89 e5                	mov    %esp,%ebp
c0104e14:	83 ec 18             	sub    $0x18,%esp
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c0104e17:	9c                   	pushf  
c0104e18:	58                   	pop    %eax
c0104e19:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c0104e1c:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c0104e1f:	25 00 02 00 00       	and    $0x200,%eax
c0104e24:	85 c0                	test   %eax,%eax
c0104e26:	74 0c                	je     c0104e34 <__intr_save+0x23>
        intr_disable();
c0104e28:	e8 ce d0 ff ff       	call   c0101efb <intr_disable>
        return 1;
c0104e2d:	b8 01 00 00 00       	mov    $0x1,%eax
c0104e32:	eb 05                	jmp    c0104e39 <__intr_save+0x28>
    return 0;
c0104e34:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0104e39:	89 ec                	mov    %ebp,%esp
c0104e3b:	5d                   	pop    %ebp
c0104e3c:	c3                   	ret    

c0104e3d <__intr_restore>:
__intr_restore(bool flag) {
c0104e3d:	55                   	push   %ebp
c0104e3e:	89 e5                	mov    %esp,%ebp
c0104e40:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c0104e43:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0104e47:	74 05                	je     c0104e4e <__intr_restore+0x11>
        intr_enable();
c0104e49:	e8 a5 d0 ff ff       	call   c0101ef3 <intr_enable>
}
c0104e4e:	90                   	nop
c0104e4f:	89 ec                	mov    %ebp,%esp
c0104e51:	5d                   	pop    %ebp
c0104e52:	c3                   	ret    

c0104e53 <lgdt>:
 * data/code segement registers for kernel.
 * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。
 * */
//定义了一个静态内联函数 lgdt，接收一个指向伪描述符（struct pseudodesc）的指针 pd
static inline void
lgdt(struct pseudodesc *pd) {
c0104e53:	55                   	push   %ebp
c0104e54:	89 e5                	mov    %esp,%ebp
    //这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针，告诉处理器 GDT 的地址。
    asm volatile ("lgdt (%0)" :: "r" (pd));
c0104e56:	8b 45 08             	mov    0x8(%ebp),%eax
c0104e59:	0f 01 10             	lgdtl  (%eax)
    asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS（用户数据段）的值移动到 gs 段寄存器。
c0104e5c:	b8 23 00 00 00       	mov    $0x23,%eax
c0104e61:	8e e8                	mov    %eax,%gs
    asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。
c0104e63:	b8 23 00 00 00       	mov    $0x23,%eax
c0104e68:	8e e0                	mov    %eax,%fs
    asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS（内核数据段）的值移动到 es 段寄存器。
c0104e6a:	b8 10 00 00 00       	mov    $0x10,%eax
c0104e6f:	8e c0                	mov    %eax,%es
    asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器
c0104e71:	b8 10 00 00 00       	mov    $0x10,%eax
c0104e76:	8e d8                	mov    %eax,%ds
    asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器
c0104e78:	b8 10 00 00 00       	mov    $0x10,%eax
c0104e7d:	8e d0                	mov    %eax,%ss
    // reload cs
    //通过 ljmp 指令重新加载代码段寄存器 cs，并跳转到标签 1。
    asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS));
c0104e7f:	ea 86 4e 10 c0 08 00 	ljmp   $0x8,$0xc0104e86
}
c0104e86:	90                   	nop
c0104e87:	5d                   	pop    %ebp
c0104e88:	c3                   	ret    

c0104e89 <load_esp0>:
 * load_esp0 - 修改默认任务状态段中的 ESP0，以便在从用户态陷入内核态时能够使用不同的内核栈。
 * */
//uintptr_t esp0：这是新的堆栈指针，通常指向内核栈的顶部。
//修改当前任务状态段（TSS）中的 ESP0 值。ESP0 是在从用户态切换到内核态时，CPU 使用的内核栈指针。
void
load_esp0(uintptr_t esp0) {
c0104e89:	55                   	push   %ebp
c0104e8a:	89 e5                	mov    %esp,%ebp
    ts.ts_esp0 = esp0;
c0104e8c:	8b 45 08             	mov    0x8(%ebp),%eax
c0104e8f:	a3 24 c0 12 c0       	mov    %eax,0xc012c024
}
c0104e94:	90                   	nop
c0104e95:	5d                   	pop    %ebp
c0104e96:	c3                   	ret    

c0104e97 <gdt_init>:

/* gdt_init - initialize the default GDT and TSS */
/* gdt_init - 初始化默认的 GDT 和 TSS */
static void
gdt_init(void) {
c0104e97:	55                   	push   %ebp
c0104e98:	89 e5                	mov    %esp,%ebp
c0104e9a:	83 ec 14             	sub    $0x14,%esp
    // 设置启动内核栈和默认的 SS0
    // set boot kernel stack and default SS0
    load_esp0((uintptr_t)bootstacktop);
c0104e9d:	b8 00 80 12 c0       	mov    $0xc0128000,%eax
c0104ea2:	89 04 24             	mov    %eax,(%esp)
c0104ea5:	e8 df ff ff ff       	call   c0104e89 <load_esp0>
    ts.ts_ss0 = KERNEL_DS;
c0104eaa:	66 c7 05 28 c0 12 c0 	movw   $0x10,0xc012c028
c0104eb1:	10 00 
    // 初始化 GDT 中的 TSS 字段
    // initialize the TSS filed of the gdt
    gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL);
c0104eb3:	66 c7 05 48 8a 12 c0 	movw   $0x68,0xc0128a48
c0104eba:	68 00 
c0104ebc:	b8 20 c0 12 c0       	mov    $0xc012c020,%eax
c0104ec1:	0f b7 c0             	movzwl %ax,%eax
c0104ec4:	66 a3 4a 8a 12 c0    	mov    %ax,0xc0128a4a
c0104eca:	b8 20 c0 12 c0       	mov    $0xc012c020,%eax
c0104ecf:	c1 e8 10             	shr    $0x10,%eax
c0104ed2:	a2 4c 8a 12 c0       	mov    %al,0xc0128a4c
c0104ed7:	0f b6 05 4d 8a 12 c0 	movzbl 0xc0128a4d,%eax
c0104ede:	24 f0                	and    $0xf0,%al
c0104ee0:	0c 09                	or     $0x9,%al
c0104ee2:	a2 4d 8a 12 c0       	mov    %al,0xc0128a4d
c0104ee7:	0f b6 05 4d 8a 12 c0 	movzbl 0xc0128a4d,%eax
c0104eee:	24 ef                	and    $0xef,%al
c0104ef0:	a2 4d 8a 12 c0       	mov    %al,0xc0128a4d
c0104ef5:	0f b6 05 4d 8a 12 c0 	movzbl 0xc0128a4d,%eax
c0104efc:	24 9f                	and    $0x9f,%al
c0104efe:	a2 4d 8a 12 c0       	mov    %al,0xc0128a4d
c0104f03:	0f b6 05 4d 8a 12 c0 	movzbl 0xc0128a4d,%eax
c0104f0a:	0c 80                	or     $0x80,%al
c0104f0c:	a2 4d 8a 12 c0       	mov    %al,0xc0128a4d
c0104f11:	0f b6 05 4e 8a 12 c0 	movzbl 0xc0128a4e,%eax
c0104f18:	24 f0                	and    $0xf0,%al
c0104f1a:	a2 4e 8a 12 c0       	mov    %al,0xc0128a4e
c0104f1f:	0f b6 05 4e 8a 12 c0 	movzbl 0xc0128a4e,%eax
c0104f26:	24 ef                	and    $0xef,%al
c0104f28:	a2 4e 8a 12 c0       	mov    %al,0xc0128a4e
c0104f2d:	0f b6 05 4e 8a 12 c0 	movzbl 0xc0128a4e,%eax
c0104f34:	24 df                	and    $0xdf,%al
c0104f36:	a2 4e 8a 12 c0       	mov    %al,0xc0128a4e
c0104f3b:	0f b6 05 4e 8a 12 c0 	movzbl 0xc0128a4e,%eax
c0104f42:	0c 40                	or     $0x40,%al
c0104f44:	a2 4e 8a 12 c0       	mov    %al,0xc0128a4e
c0104f49:	0f b6 05 4e 8a 12 c0 	movzbl 0xc0128a4e,%eax
c0104f50:	24 7f                	and    $0x7f,%al
c0104f52:	a2 4e 8a 12 c0       	mov    %al,0xc0128a4e
c0104f57:	b8 20 c0 12 c0       	mov    $0xc012c020,%eax
c0104f5c:	c1 e8 18             	shr    $0x18,%eax
c0104f5f:	a2 4f 8a 12 c0       	mov    %al,0xc0128a4f
    // 使用lgdt加载全局描述符表，更新所有段寄存器
    // reload all segment registers
    lgdt(&gdt_pd);
c0104f64:	c7 04 24 50 8a 12 c0 	movl   $0xc0128a50,(%esp)
c0104f6b:	e8 e3 fe ff ff       	call   c0104e53 <lgdt>
c0104f70:	66 c7 45 fe 28 00    	movw   $0x28,-0x2(%ebp)
    asm volatile ("ltr %0" :: "r" (sel) : "memory");
c0104f76:	0f b7 45 fe          	movzwl -0x2(%ebp),%eax
c0104f7a:	0f 00 d8             	ltr    %ax
}
c0104f7d:	90                   	nop
    // 加载 TSS，使 CPU 在进行特权级切换时能够正确使用 TSS。
    // load the TSS
    ltr(GD_TSS);
}
c0104f7e:	90                   	nop
c0104f7f:	89 ec                	mov    %ebp,%esp
c0104f81:	5d                   	pop    %ebp
c0104f82:	c3                   	ret    

c0104f83 <init_pmm_manager>:

//init_pmm_manager - initialize a pmm_manager instance
//初始化一个 pmm_manager 实例
static void
init_pmm_manager(void) {
c0104f83:	55                   	push   %ebp
c0104f84:	89 e5                	mov    %esp,%ebp
c0104f86:	83 ec 18             	sub    $0x18,%esp
    //将 pmm_manager 指向默认的 PMM 管理器实例。
    pmm_manager = &default_pmm_manager;
c0104f89:	c7 05 0c c0 12 c0 00 	movl   $0xc010ad00,0xc012c00c
c0104f90:	ad 10 c0 
     //使用 cprintf 打印当前内存管理器的名称。
    cprintf("memory management: %s\n", pmm_manager->name);
c0104f93:	a1 0c c0 12 c0       	mov    0xc012c00c,%eax
c0104f98:	8b 00                	mov    (%eax),%eax
c0104f9a:	89 44 24 04          	mov    %eax,0x4(%esp)
c0104f9e:	c7 04 24 8c ae 10 c0 	movl   $0xc010ae8c,(%esp)
c0104fa5:	e8 ce b3 ff ff       	call   c0100378 <cprintf>
    //调用 PMM 管理器的初始化函数，以设置和准备内存管理的相关数据结构。
    pmm_manager->init();
c0104faa:	a1 0c c0 12 c0       	mov    0xc012c00c,%eax
c0104faf:	8b 40 04             	mov    0x4(%eax),%eax
c0104fb2:	ff d0                	call   *%eax
}
c0104fb4:	90                   	nop
c0104fb5:	89 ec                	mov    %ebp,%esp
c0104fb7:	5d                   	pop    %ebp
c0104fb8:	c3                   	ret    

c0104fb9 <init_memmap>:

//init_memmap - call pmm->init_memmap to build Page struct for free memory 
// init_memmap - 调用 pmm->init_memmap 构建空闲内存的 Page 结构
//struct Page *base：指向内存页的基础地址。 size_t n：要初始化的页数。 
static void
init_memmap(struct Page *base, size_t n) {
c0104fb9:	55                   	push   %ebp
c0104fba:	89 e5                	mov    %esp,%ebp
c0104fbc:	83 ec 18             	sub    $0x18,%esp
    pmm_manager->init_memmap(base, n);
c0104fbf:	a1 0c c0 12 c0       	mov    0xc012c00c,%eax
c0104fc4:	8b 40 08             	mov    0x8(%eax),%eax
c0104fc7:	8b 55 0c             	mov    0xc(%ebp),%edx
c0104fca:	89 54 24 04          	mov    %edx,0x4(%esp)
c0104fce:	8b 55 08             	mov    0x8(%ebp),%edx
c0104fd1:	89 14 24             	mov    %edx,(%esp)
c0104fd4:	ff d0                	call   *%eax
}
c0104fd6:	90                   	nop
c0104fd7:	89 ec                	mov    %ebp,%esp
c0104fd9:	5d                   	pop    %ebp
c0104fda:	c3                   	ret    

c0104fdb <alloc_pages>:

//alloc_pages - call pmm->alloc_pages to allocate a continuous n*PAGESIZE memory 
// alloc_pages - 调用 pmm->alloc_pages 分配连续的 n*PAGESIZE 内存
struct Page *
alloc_pages(size_t n) {
c0104fdb:	55                   	push   %ebp
c0104fdc:	89 e5                	mov    %esp,%ebp
c0104fde:	83 ec 28             	sub    $0x28,%esp
    struct Page *page=NULL;
c0104fe1:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    bool intr_flag;
    //使用 local_intr_save 保存当前的中断状态，以避免在分配内存时发生中断。    
    while (1)
    {
         local_intr_save(intr_flag);
c0104fe8:	e8 24 fe ff ff       	call   c0104e11 <__intr_save>
c0104fed:	89 45 f0             	mov    %eax,-0x10(%ebp)
         {
              page = pmm_manager->alloc_pages(n);//尝试分配 n 个页面。
c0104ff0:	a1 0c c0 12 c0       	mov    0xc012c00c,%eax
c0104ff5:	8b 40 0c             	mov    0xc(%eax),%eax
c0104ff8:	8b 55 08             	mov    0x8(%ebp),%edx
c0104ffb:	89 14 24             	mov    %edx,(%esp)
c0104ffe:	ff d0                	call   *%eax
c0105000:	89 45 f4             	mov    %eax,-0xc(%ebp)
         }
         local_intr_restore(intr_flag);
c0105003:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105006:	89 04 24             	mov    %eax,(%esp)
c0105009:	e8 2f fe ff ff       	call   c0104e3d <__intr_restore>

         if (page != NULL || n > 1 || swap_init_ok == 0) break;
c010500e:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105012:	75 2d                	jne    c0105041 <alloc_pages+0x66>
c0105014:	83 7d 08 01          	cmpl   $0x1,0x8(%ebp)
c0105018:	77 27                	ja     c0105041 <alloc_pages+0x66>
c010501a:	a1 a4 c0 12 c0       	mov    0xc012c0a4,%eax
c010501f:	85 c0                	test   %eax,%eax
c0105021:	74 1e                	je     c0105041 <alloc_pages+0x66>
         
         extern struct mm_struct *check_mm_struct;
         //cprintf("page %x, call swap_out in alloc_pages %d\n",page, n);
         swap_out(check_mm_struct, n, 0);
c0105023:	8b 55 08             	mov    0x8(%ebp),%edx
c0105026:	a1 6c c1 12 c0       	mov    0xc012c16c,%eax
c010502b:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105032:	00 
c0105033:	89 54 24 04          	mov    %edx,0x4(%esp)
c0105037:	89 04 24             	mov    %eax,(%esp)
c010503a:	e8 c5 18 00 00       	call   c0106904 <swap_out>
    {
c010503f:	eb a7                	jmp    c0104fe8 <alloc_pages+0xd>
    }
    //cprintf("n %d,get page %x, No %d in alloc_pages\n",n,page,(page-pages));
    return page;
c0105041:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0105044:	89 ec                	mov    %ebp,%esp
c0105046:	5d                   	pop    %ebp
c0105047:	c3                   	ret    

c0105048 <free_pages>:

//free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory 
// free_pages - 调用 pmm->free_pages 释放连续的 n*PAGESIZE 内存
//struct Page *base：指向要释放的内存页的基础地址。size_t n：要释放的页数。
void
free_pages(struct Page *base, size_t n) {
c0105048:	55                   	push   %ebp
c0105049:	89 e5                	mov    %esp,%ebp
c010504b:	83 ec 28             	sub    $0x28,%esp
    bool intr_flag;
    //使用 local_intr_save 保存当前的中断状态，以避免在释放内存时发生中断。
    local_intr_save(intr_flag);
c010504e:	e8 be fd ff ff       	call   c0104e11 <__intr_save>
c0105053:	89 45 f4             	mov    %eax,-0xc(%ebp)
    {
        //调用物理内存管理器的 free_pages 函数释放 n 页的内存。
        pmm_manager->free_pages(base, n);
c0105056:	a1 0c c0 12 c0       	mov    0xc012c00c,%eax
c010505b:	8b 40 10             	mov    0x10(%eax),%eax
c010505e:	8b 55 0c             	mov    0xc(%ebp),%edx
c0105061:	89 54 24 04          	mov    %edx,0x4(%esp)
c0105065:	8b 55 08             	mov    0x8(%ebp),%edx
c0105068:	89 14 24             	mov    %edx,(%esp)
c010506b:	ff d0                	call   *%eax
    }
    local_intr_restore(intr_flag);
c010506d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105070:	89 04 24             	mov    %eax,(%esp)
c0105073:	e8 c5 fd ff ff       	call   c0104e3d <__intr_restore>
}
c0105078:	90                   	nop
c0105079:	89 ec                	mov    %ebp,%esp
c010507b:	5d                   	pop    %ebp
c010507c:	c3                   	ret    

c010507d <nr_free_pages>:

//nr_free_pages - call pmm->nr_free_pages to get the size (nr*PAGESIZE) 
//of current free memory
// nr_free_pages - 调用 pmm->nr_free_pages 获取当前空闲内存的大小 (nr * PAGESIZE)
size_t
nr_free_pages(void) {
c010507d:	55                   	push   %ebp
c010507e:	89 e5                	mov    %esp,%ebp
c0105080:	83 ec 28             	sub    $0x28,%esp
    size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小
    bool intr_flag;// 定义变量 intr_flag 用于保存中断状态
    local_intr_save(intr_flag);// 保存当前中断状态，并禁用中断
c0105083:	e8 89 fd ff ff       	call   c0104e11 <__intr_save>
c0105088:	89 45 f4             	mov    %eax,-0xc(%ebp)
    {
        ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数
c010508b:	a1 0c c0 12 c0       	mov    0xc012c00c,%eax
c0105090:	8b 40 14             	mov    0x14(%eax),%eax
c0105093:	ff d0                	call   *%eax
c0105095:	89 45 f0             	mov    %eax,-0x10(%ebp)
    }
    local_intr_restore(intr_flag);// 恢复之前保存的中断状态
c0105098:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010509b:	89 04 24             	mov    %eax,(%esp)
c010509e:	e8 9a fd ff ff       	call   c0104e3d <__intr_restore>
    return ret;// 返回空闲内存的大小
c01050a3:	8b 45 f0             	mov    -0x10(%ebp),%eax
}
c01050a6:	89 ec                	mov    %ebp,%esp
c01050a8:	5d                   	pop    %ebp
c01050a9:	c3                   	ret    

c01050aa <page_init>:

/* pmm_init - initialize the physical memory management */
/* pmm_init - 初始化物理内存管理 */
static void
page_init(void) {
c01050aa:	55                   	push   %ebp
c01050ab:	89 e5                	mov    %esp,%ebp
c01050ad:	57                   	push   %edi
c01050ae:	56                   	push   %esi
c01050af:	53                   	push   %ebx
c01050b0:	81 ec 9c 00 00 00    	sub    $0x9c,%esp
    // 获取物理内存映射信息，存于特定地址
    struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE);
c01050b6:	c7 45 c4 00 80 00 c0 	movl   $0xc0008000,-0x3c(%ebp)
    uint64_t maxpa = 0;// 初始化最大物理地址为0
c01050bd:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
c01050c4:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
    
    cprintf("e820map:\n");// 打印“e820map”标题
c01050cb:	c7 04 24 a3 ae 10 c0 	movl   $0xc010aea3,(%esp)
c01050d2:	e8 a1 b2 ff ff       	call   c0100378 <cprintf>
    int i;
    for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组
c01050d7:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c01050de:	e9 0c 01 00 00       	jmp    c01051ef <page_init+0x145>
        uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址
c01050e3:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01050e6:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01050e9:	89 d0                	mov    %edx,%eax
c01050eb:	c1 e0 02             	shl    $0x2,%eax
c01050ee:	01 d0                	add    %edx,%eax
c01050f0:	c1 e0 02             	shl    $0x2,%eax
c01050f3:	01 c8                	add    %ecx,%eax
c01050f5:	8b 50 08             	mov    0x8(%eax),%edx
c01050f8:	8b 40 04             	mov    0x4(%eax),%eax
c01050fb:	89 45 a0             	mov    %eax,-0x60(%ebp)
c01050fe:	89 55 a4             	mov    %edx,-0x5c(%ebp)
c0105101:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c0105104:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0105107:	89 d0                	mov    %edx,%eax
c0105109:	c1 e0 02             	shl    $0x2,%eax
c010510c:	01 d0                	add    %edx,%eax
c010510e:	c1 e0 02             	shl    $0x2,%eax
c0105111:	01 c8                	add    %ecx,%eax
c0105113:	8b 48 0c             	mov    0xc(%eax),%ecx
c0105116:	8b 58 10             	mov    0x10(%eax),%ebx
c0105119:	8b 45 a0             	mov    -0x60(%ebp),%eax
c010511c:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c010511f:	01 c8                	add    %ecx,%eax
c0105121:	11 da                	adc    %ebx,%edx
c0105123:	89 45 98             	mov    %eax,-0x68(%ebp)
c0105126:	89 55 9c             	mov    %edx,-0x64(%ebp)
        cprintf("  memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息
c0105129:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c010512c:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010512f:	89 d0                	mov    %edx,%eax
c0105131:	c1 e0 02             	shl    $0x2,%eax
c0105134:	01 d0                	add    %edx,%eax
c0105136:	c1 e0 02             	shl    $0x2,%eax
c0105139:	01 c8                	add    %ecx,%eax
c010513b:	83 c0 14             	add    $0x14,%eax
c010513e:	8b 00                	mov    (%eax),%eax
c0105140:	89 85 7c ff ff ff    	mov    %eax,-0x84(%ebp)
c0105146:	8b 45 98             	mov    -0x68(%ebp),%eax
c0105149:	8b 55 9c             	mov    -0x64(%ebp),%edx
c010514c:	83 c0 ff             	add    $0xffffffff,%eax
c010514f:	83 d2 ff             	adc    $0xffffffff,%edx
c0105152:	89 c6                	mov    %eax,%esi
c0105154:	89 d7                	mov    %edx,%edi
c0105156:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c0105159:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010515c:	89 d0                	mov    %edx,%eax
c010515e:	c1 e0 02             	shl    $0x2,%eax
c0105161:	01 d0                	add    %edx,%eax
c0105163:	c1 e0 02             	shl    $0x2,%eax
c0105166:	01 c8                	add    %ecx,%eax
c0105168:	8b 48 0c             	mov    0xc(%eax),%ecx
c010516b:	8b 58 10             	mov    0x10(%eax),%ebx
c010516e:	8b 85 7c ff ff ff    	mov    -0x84(%ebp),%eax
c0105174:	89 44 24 1c          	mov    %eax,0x1c(%esp)
c0105178:	89 74 24 14          	mov    %esi,0x14(%esp)
c010517c:	89 7c 24 18          	mov    %edi,0x18(%esp)
c0105180:	8b 45 a0             	mov    -0x60(%ebp),%eax
c0105183:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c0105186:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010518a:	89 54 24 10          	mov    %edx,0x10(%esp)
c010518e:	89 4c 24 04          	mov    %ecx,0x4(%esp)
c0105192:	89 5c 24 08          	mov    %ebx,0x8(%esp)
c0105196:	c7 04 24 b0 ae 10 c0 	movl   $0xc010aeb0,(%esp)
c010519d:	e8 d6 b1 ff ff       	call   c0100378 <cprintf>
                memmap->map[i].size, begin, end - 1, memmap->map[i].type);
        if (memmap->map[i].type == E820_ARM) {// 检查内存类型是否为可用内存
c01051a2:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01051a5:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01051a8:	89 d0                	mov    %edx,%eax
c01051aa:	c1 e0 02             	shl    $0x2,%eax
c01051ad:	01 d0                	add    %edx,%eax
c01051af:	c1 e0 02             	shl    $0x2,%eax
c01051b2:	01 c8                	add    %ecx,%eax
c01051b4:	83 c0 14             	add    $0x14,%eax
c01051b7:	8b 00                	mov    (%eax),%eax
c01051b9:	83 f8 01             	cmp    $0x1,%eax
c01051bc:	75 2e                	jne    c01051ec <page_init+0x142>
            if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内
c01051be:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01051c1:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c01051c4:	3b 45 98             	cmp    -0x68(%ebp),%eax
c01051c7:	89 d0                	mov    %edx,%eax
c01051c9:	1b 45 9c             	sbb    -0x64(%ebp),%eax
c01051cc:	73 1e                	jae    c01051ec <page_init+0x142>
c01051ce:	ba ff ff ff 37       	mov    $0x37ffffff,%edx
c01051d3:	b8 00 00 00 00       	mov    $0x0,%eax
c01051d8:	3b 55 a0             	cmp    -0x60(%ebp),%edx
c01051db:	1b 45 a4             	sbb    -0x5c(%ebp),%eax
c01051de:	72 0c                	jb     c01051ec <page_init+0x142>
                maxpa = end;// 更新最大物理地址
c01051e0:	8b 45 98             	mov    -0x68(%ebp),%eax
c01051e3:	8b 55 9c             	mov    -0x64(%ebp),%edx
c01051e6:	89 45 e0             	mov    %eax,-0x20(%ebp)
c01051e9:	89 55 e4             	mov    %edx,-0x1c(%ebp)
    for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组
c01051ec:	ff 45 dc             	incl   -0x24(%ebp)
c01051ef:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c01051f2:	8b 00                	mov    (%eax),%eax
c01051f4:	39 45 dc             	cmp    %eax,-0x24(%ebp)
c01051f7:	0f 8c e6 fe ff ff    	jl     c01050e3 <page_init+0x39>
            }
        }
    }
    if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限
c01051fd:	ba 00 00 00 38       	mov    $0x38000000,%edx
c0105202:	b8 00 00 00 00       	mov    $0x0,%eax
c0105207:	3b 55 e0             	cmp    -0x20(%ebp),%edx
c010520a:	1b 45 e4             	sbb    -0x1c(%ebp),%eax
c010520d:	73 0e                	jae    c010521d <page_init+0x173>
        maxpa = KMEMSIZE;// 将其限制为内存上限
c010520f:	c7 45 e0 00 00 00 38 	movl   $0x38000000,-0x20(%ebp)
c0105216:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
    }

    extern char end[];// 引入全局变量 end，指向内存的结束位置

    npage = maxpa / PGSIZE;// 计算可用页数
c010521d:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0105220:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0105223:	0f ac d0 0c          	shrd   $0xc,%edx,%eax
c0105227:	c1 ea 0c             	shr    $0xc,%edx
c010522a:	a3 04 c0 12 c0       	mov    %eax,0xc012c004
    pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界，指向页结构数组的开头
c010522f:	c7 45 c0 00 10 00 00 	movl   $0x1000,-0x40(%ebp)
c0105236:	b8 b4 e1 12 c0       	mov    $0xc012e1b4,%eax
c010523b:	8d 50 ff             	lea    -0x1(%eax),%edx
c010523e:	8b 45 c0             	mov    -0x40(%ebp),%eax
c0105241:	01 d0                	add    %edx,%eax
c0105243:	89 45 bc             	mov    %eax,-0x44(%ebp)
c0105246:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0105249:	ba 00 00 00 00       	mov    $0x0,%edx
c010524e:	f7 75 c0             	divl   -0x40(%ebp)
c0105251:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0105254:	29 d0                	sub    %edx,%eax
c0105256:	a3 00 c0 12 c0       	mov    %eax,0xc012c000

    for (i = 0; i < npage; i ++) {// 遍历每一页
c010525b:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c0105262:	eb 28                	jmp    c010528c <page_init+0x1e2>
        SetPageReserved(pages + i);// 将每一页标记为保留状态
c0105264:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c010526a:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010526d:	c1 e0 05             	shl    $0x5,%eax
c0105270:	01 d0                	add    %edx,%eax
c0105272:	83 c0 04             	add    $0x4,%eax
c0105275:	c7 45 94 00 00 00 00 	movl   $0x0,-0x6c(%ebp)
c010527c:	89 45 90             	mov    %eax,-0x70(%ebp)
    asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr));
c010527f:	8b 45 90             	mov    -0x70(%ebp),%eax
c0105282:	8b 55 94             	mov    -0x6c(%ebp),%edx
c0105285:	0f ab 10             	bts    %edx,(%eax)
}
c0105288:	90                   	nop
    for (i = 0; i < npage; i ++) {// 遍历每一页
c0105289:	ff 45 dc             	incl   -0x24(%ebp)
c010528c:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010528f:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c0105294:	39 c2                	cmp    %eax,%edx
c0105296:	72 cc                	jb     c0105264 <page_init+0x1ba>
    }

    uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址
c0105298:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c010529d:	c1 e0 05             	shl    $0x5,%eax
c01052a0:	89 c2                	mov    %eax,%edx
c01052a2:	a1 00 c0 12 c0       	mov    0xc012c000,%eax
c01052a7:	01 d0                	add    %edx,%eax
c01052a9:	89 45 b8             	mov    %eax,-0x48(%ebp)
c01052ac:	81 7d b8 ff ff ff bf 	cmpl   $0xbfffffff,-0x48(%ebp)
c01052b3:	77 23                	ja     c01052d8 <page_init+0x22e>
c01052b5:	8b 45 b8             	mov    -0x48(%ebp),%eax
c01052b8:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01052bc:	c7 44 24 08 e0 ae 10 	movl   $0xc010aee0,0x8(%esp)
c01052c3:	c0 
c01052c4:	c7 44 24 04 1a 01 00 	movl   $0x11a,0x4(%esp)
c01052cb:	00 
c01052cc:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01052d3:	e8 6d b9 ff ff       	call   c0100c45 <__panic>
c01052d8:	8b 45 b8             	mov    -0x48(%ebp),%eax
c01052db:	05 00 00 00 40       	add    $0x40000000,%eax
c01052e0:	89 45 b4             	mov    %eax,-0x4c(%ebp)

    for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射
c01052e3:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c01052ea:	e9 53 01 00 00       	jmp    c0105442 <page_init+0x398>
        uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址
c01052ef:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c01052f2:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01052f5:	89 d0                	mov    %edx,%eax
c01052f7:	c1 e0 02             	shl    $0x2,%eax
c01052fa:	01 d0                	add    %edx,%eax
c01052fc:	c1 e0 02             	shl    $0x2,%eax
c01052ff:	01 c8                	add    %ecx,%eax
c0105301:	8b 50 08             	mov    0x8(%eax),%edx
c0105304:	8b 40 04             	mov    0x4(%eax),%eax
c0105307:	89 45 d0             	mov    %eax,-0x30(%ebp)
c010530a:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c010530d:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c0105310:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0105313:	89 d0                	mov    %edx,%eax
c0105315:	c1 e0 02             	shl    $0x2,%eax
c0105318:	01 d0                	add    %edx,%eax
c010531a:	c1 e0 02             	shl    $0x2,%eax
c010531d:	01 c8                	add    %ecx,%eax
c010531f:	8b 48 0c             	mov    0xc(%eax),%ecx
c0105322:	8b 58 10             	mov    0x10(%eax),%ebx
c0105325:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0105328:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010532b:	01 c8                	add    %ecx,%eax
c010532d:	11 da                	adc    %ebx,%edx
c010532f:	89 45 c8             	mov    %eax,-0x38(%ebp)
c0105332:	89 55 cc             	mov    %edx,-0x34(%ebp)
        if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存
c0105335:	8b 4d c4             	mov    -0x3c(%ebp),%ecx
c0105338:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010533b:	89 d0                	mov    %edx,%eax
c010533d:	c1 e0 02             	shl    $0x2,%eax
c0105340:	01 d0                	add    %edx,%eax
c0105342:	c1 e0 02             	shl    $0x2,%eax
c0105345:	01 c8                	add    %ecx,%eax
c0105347:	83 c0 14             	add    $0x14,%eax
c010534a:	8b 00                	mov    (%eax),%eax
c010534c:	83 f8 01             	cmp    $0x1,%eax
c010534f:	0f 85 ea 00 00 00    	jne    c010543f <page_init+0x395>
            if (begin < freemem) {// 如果起始地址小于可用内存地址
c0105355:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0105358:	ba 00 00 00 00       	mov    $0x0,%edx
c010535d:	8b 4d d4             	mov    -0x2c(%ebp),%ecx
c0105360:	39 45 d0             	cmp    %eax,-0x30(%ebp)
c0105363:	19 d1                	sbb    %edx,%ecx
c0105365:	73 0d                	jae    c0105374 <page_init+0x2ca>
                begin = freemem;//将起始地址设置为可用内存地址
c0105367:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c010536a:	89 45 d0             	mov    %eax,-0x30(%ebp)
c010536d:	c7 45 d4 00 00 00 00 	movl   $0x0,-0x2c(%ebp)
            }
            if (end > KMEMSIZE) {// 如果结束地址超过内存上限
c0105374:	ba 00 00 00 38       	mov    $0x38000000,%edx
c0105379:	b8 00 00 00 00       	mov    $0x0,%eax
c010537e:	3b 55 c8             	cmp    -0x38(%ebp),%edx
c0105381:	1b 45 cc             	sbb    -0x34(%ebp),%eax
c0105384:	73 0e                	jae    c0105394 <page_init+0x2ea>
                end = KMEMSIZE;// 将其限制为内存上限
c0105386:	c7 45 c8 00 00 00 38 	movl   $0x38000000,-0x38(%ebp)
c010538d:	c7 45 cc 00 00 00 00 	movl   $0x0,-0x34(%ebp)
            }
            if (begin < end) {// 如果起始地址小于结束地址
c0105394:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0105397:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010539a:	3b 45 c8             	cmp    -0x38(%ebp),%eax
c010539d:	89 d0                	mov    %edx,%eax
c010539f:	1b 45 cc             	sbb    -0x34(%ebp),%eax
c01053a2:	0f 83 97 00 00 00    	jae    c010543f <page_init+0x395>
                begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界
c01053a8:	c7 45 b0 00 10 00 00 	movl   $0x1000,-0x50(%ebp)
c01053af:	8b 55 d0             	mov    -0x30(%ebp),%edx
c01053b2:	8b 45 b0             	mov    -0x50(%ebp),%eax
c01053b5:	01 d0                	add    %edx,%eax
c01053b7:	48                   	dec    %eax
c01053b8:	89 45 ac             	mov    %eax,-0x54(%ebp)
c01053bb:	8b 45 ac             	mov    -0x54(%ebp),%eax
c01053be:	ba 00 00 00 00       	mov    $0x0,%edx
c01053c3:	f7 75 b0             	divl   -0x50(%ebp)
c01053c6:	8b 45 ac             	mov    -0x54(%ebp),%eax
c01053c9:	29 d0                	sub    %edx,%eax
c01053cb:	ba 00 00 00 00       	mov    $0x0,%edx
c01053d0:	89 45 d0             	mov    %eax,-0x30(%ebp)
c01053d3:	89 55 d4             	mov    %edx,-0x2c(%ebp)
                end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界
c01053d6:	8b 45 c8             	mov    -0x38(%ebp),%eax
c01053d9:	89 45 a8             	mov    %eax,-0x58(%ebp)
c01053dc:	8b 45 a8             	mov    -0x58(%ebp),%eax
c01053df:	ba 00 00 00 00       	mov    $0x0,%edx
c01053e4:	89 c7                	mov    %eax,%edi
c01053e6:	81 e7 00 f0 ff ff    	and    $0xfffff000,%edi
c01053ec:	89 7d 80             	mov    %edi,-0x80(%ebp)
c01053ef:	89 d0                	mov    %edx,%eax
c01053f1:	83 e0 00             	and    $0x0,%eax
c01053f4:	89 45 84             	mov    %eax,-0x7c(%ebp)
c01053f7:	8b 45 80             	mov    -0x80(%ebp),%eax
c01053fa:	8b 55 84             	mov    -0x7c(%ebp),%edx
c01053fd:	89 45 c8             	mov    %eax,-0x38(%ebp)
c0105400:	89 55 cc             	mov    %edx,-0x34(%ebp)
                if (begin < end) {// 如果调整后的起始地址仍小于结束地址
c0105403:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0105406:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0105409:	3b 45 c8             	cmp    -0x38(%ebp),%eax
c010540c:	89 d0                	mov    %edx,%eax
c010540e:	1b 45 cc             	sbb    -0x34(%ebp),%eax
c0105411:	73 2c                	jae    c010543f <page_init+0x395>
                    init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射
c0105413:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0105416:	8b 55 cc             	mov    -0x34(%ebp),%edx
c0105419:	2b 45 d0             	sub    -0x30(%ebp),%eax
c010541c:	1b 55 d4             	sbb    -0x2c(%ebp),%edx
c010541f:	0f ac d0 0c          	shrd   $0xc,%edx,%eax
c0105423:	c1 ea 0c             	shr    $0xc,%edx
c0105426:	89 c3                	mov    %eax,%ebx
c0105428:	8b 45 d0             	mov    -0x30(%ebp),%eax
c010542b:	89 04 24             	mov    %eax,(%esp)
c010542e:	e8 a0 f8 ff ff       	call   c0104cd3 <pa2page>
c0105433:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c0105437:	89 04 24             	mov    %eax,(%esp)
c010543a:	e8 7a fb ff ff       	call   c0104fb9 <init_memmap>
    for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射
c010543f:	ff 45 dc             	incl   -0x24(%ebp)
c0105442:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0105445:	8b 00                	mov    (%eax),%eax
c0105447:	39 45 dc             	cmp    %eax,-0x24(%ebp)
c010544a:	0f 8c 9f fe ff ff    	jl     c01052ef <page_init+0x245>
                }
            }
        }
    }
}
c0105450:	90                   	nop
c0105451:	90                   	nop
c0105452:	81 c4 9c 00 00 00    	add    $0x9c,%esp
c0105458:	5b                   	pop    %ebx
c0105459:	5e                   	pop    %esi
c010545a:	5f                   	pop    %edi
c010545b:	5d                   	pop    %ebp
c010545c:	c3                   	ret    

c010545d <boot_map_segment>:
//la:   需要映射的线性地址（经过 x86 段映射后的地址）
//  size: memory size   size: 内存大小
//  pa:   physical address of this memory  pa:该内存的物理地址
//  perm: permission of this memory    perm: 该内存的权限
static void
boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t perm) {
c010545d:	55                   	push   %ebp
c010545e:	89 e5                	mov    %esp,%ebp
c0105460:	83 ec 38             	sub    $0x38,%esp
    // 确保线性地址和物理地址的页偏移相同
    assert(PGOFF(la) == PGOFF(pa));
c0105463:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105466:	33 45 14             	xor    0x14(%ebp),%eax
c0105469:	25 ff 0f 00 00       	and    $0xfff,%eax
c010546e:	85 c0                	test   %eax,%eax
c0105470:	74 24                	je     c0105496 <boot_map_segment+0x39>
c0105472:	c7 44 24 0c 12 af 10 	movl   $0xc010af12,0xc(%esp)
c0105479:	c0 
c010547a:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105481:	c0 
c0105482:	c7 44 24 04 3b 01 00 	movl   $0x13b,0x4(%esp)
c0105489:	00 
c010548a:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105491:	e8 af b7 ff ff       	call   c0100c45 <__panic>
    // 计算需要映射的页数，ROUNDUP 将总大小对齐到下一个页大小的边界
    size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE;
c0105496:	c7 45 f0 00 10 00 00 	movl   $0x1000,-0x10(%ebp)
c010549d:	8b 45 0c             	mov    0xc(%ebp),%eax
c01054a0:	25 ff 0f 00 00       	and    $0xfff,%eax
c01054a5:	89 c2                	mov    %eax,%edx
c01054a7:	8b 45 10             	mov    0x10(%ebp),%eax
c01054aa:	01 c2                	add    %eax,%edx
c01054ac:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01054af:	01 d0                	add    %edx,%eax
c01054b1:	48                   	dec    %eax
c01054b2:	89 45 ec             	mov    %eax,-0x14(%ebp)
c01054b5:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01054b8:	ba 00 00 00 00       	mov    $0x0,%edx
c01054bd:	f7 75 f0             	divl   -0x10(%ebp)
c01054c0:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01054c3:	29 d0                	sub    %edx,%eax
c01054c5:	c1 e8 0c             	shr    $0xc,%eax
c01054c8:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 将线性地址向下对齐到页边界
    la = ROUNDDOWN(la, PGSIZE);
c01054cb:	8b 45 0c             	mov    0xc(%ebp),%eax
c01054ce:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01054d1:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01054d4:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c01054d9:	89 45 0c             	mov    %eax,0xc(%ebp)
    // 将物理地址向下对齐到页边界
    pa = ROUNDDOWN(pa, PGSIZE);
c01054dc:	8b 45 14             	mov    0x14(%ebp),%eax
c01054df:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c01054e2:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01054e5:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c01054ea:	89 45 14             	mov    %eax,0x14(%ebp)
    // 循环遍历每一页，直到映射的页数为零
    for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) {
c01054ed:	eb 68                	jmp    c0105557 <boot_map_segment+0xfa>
        // 获取当前页的页表项指针，如果不存在则创建新的页表项
        pte_t *ptep = get_pte(pgdir, la, 1);
c01054ef:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c01054f6:	00 
c01054f7:	8b 45 0c             	mov    0xc(%ebp),%eax
c01054fa:	89 44 24 04          	mov    %eax,0x4(%esp)
c01054fe:	8b 45 08             	mov    0x8(%ebp),%eax
c0105501:	89 04 24             	mov    %eax,(%esp)
c0105504:	e8 8d 01 00 00       	call   c0105696 <get_pte>
c0105509:	89 45 e0             	mov    %eax,-0x20(%ebp)
        // 确保页表项指针不为空
        assert(ptep != NULL);
c010550c:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c0105510:	75 24                	jne    c0105536 <boot_map_segment+0xd9>
c0105512:	c7 44 24 0c 3e af 10 	movl   $0xc010af3e,0xc(%esp)
c0105519:	c0 
c010551a:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105521:	c0 
c0105522:	c7 44 24 04 47 01 00 	movl   $0x147,0x4(%esp)
c0105529:	00 
c010552a:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105531:	e8 0f b7 ff ff       	call   c0100c45 <__panic>
         // 设置页表项，包含物理地址、存在位和权限
        *ptep = pa | PTE_P | perm;
c0105536:	8b 45 14             	mov    0x14(%ebp),%eax
c0105539:	0b 45 18             	or     0x18(%ebp),%eax
c010553c:	83 c8 01             	or     $0x1,%eax
c010553f:	89 c2                	mov    %eax,%edx
c0105541:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0105544:	89 10                	mov    %edx,(%eax)
    for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) {
c0105546:	ff 4d f4             	decl   -0xc(%ebp)
c0105549:	81 45 0c 00 10 00 00 	addl   $0x1000,0xc(%ebp)
c0105550:	81 45 14 00 10 00 00 	addl   $0x1000,0x14(%ebp)
c0105557:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010555b:	75 92                	jne    c01054ef <boot_map_segment+0x92>
    }
}
c010555d:	90                   	nop
c010555e:	90                   	nop
c010555f:	89 ec                	mov    %ebp,%esp
c0105561:	5d                   	pop    %ebp
c0105562:	c3                   	ret    

c0105563 <boot_alloc_page>:
// return value: the kernel virtual address of this allocated page
//note: this function is used to get the memory for PDT(Page Directory Table)&PT(Page Table)
//boot_alloc_page - 使用 pmm->alloc_pages(1) 分配一页内存.返回值: 分配的页面的内核虚拟地址
//注意: 此函数用于获取页目录表(PDT)和页表(PT)的内存
static void *
boot_alloc_page(void) {
c0105563:	55                   	push   %ebp
c0105564:	89 e5                	mov    %esp,%ebp
c0105566:	83 ec 28             	sub    $0x28,%esp
    struct Page *p = alloc_page();// 调用分配页面的函数
c0105569:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0105570:	e8 66 fa ff ff       	call   c0104fdb <alloc_pages>
c0105575:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (p == NULL) {// 检查分配是否成功
c0105578:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010557c:	75 1c                	jne    c010559a <boot_alloc_page+0x37>
        panic("boot_alloc_page failed.\n");// 如果分配失败，则触发异常
c010557e:	c7 44 24 08 4b af 10 	movl   $0xc010af4b,0x8(%esp)
c0105585:	c0 
c0105586:	c7 44 24 04 56 01 00 	movl   $0x156,0x4(%esp)
c010558d:	00 
c010558e:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105595:	e8 ab b6 ff ff       	call   c0100c45 <__panic>
    }
    return page2kva(p);// 返回分配页面的内核虚拟地址
c010559a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010559d:	89 04 24             	mov    %eax,(%esp)
c01055a0:	e8 76 f7 ff ff       	call   c0104d1b <page2kva>
}
c01055a5:	89 ec                	mov    %ebp,%esp
c01055a7:	5d                   	pop    %ebp
c01055a8:	c3                   	ret    

c01055a9 <pmm_init>:
//pmm_init - setup a pmm to manage physical memory, build PDT&PT to setup paging mechanism 
//         - check the correctness of pmm & paging mechanism, print PDT&PT
//pmm_init - 设置物理内存管理器，构建页目录表(PDT)和页表(PT)，以设置分页机制
//           - 检查物理内存管理器和分页机制的正确性，打印页目录表和页表
void
pmm_init(void) {
c01055a9:	55                   	push   %ebp
c01055aa:	89 e5                	mov    %esp,%ebp
c01055ac:	83 ec 38             	sub    $0x38,%esp
    // We've already enabled paging
    // 我们已经启用了分页
    boot_cr3 = PADDR(boot_pgdir);
c01055af:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c01055b4:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01055b7:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c01055be:	77 23                	ja     c01055e3 <pmm_init+0x3a>
c01055c0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01055c3:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01055c7:	c7 44 24 08 e0 ae 10 	movl   $0xc010aee0,0x8(%esp)
c01055ce:	c0 
c01055cf:	c7 44 24 04 63 01 00 	movl   $0x163,0x4(%esp)
c01055d6:	00 
c01055d7:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01055de:	e8 62 b6 ff ff       	call   c0100c45 <__panic>
c01055e3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01055e6:	05 00 00 00 40       	add    $0x40000000,%eax
c01055eb:	a3 08 c0 12 c0       	mov    %eax,0xc012c008
     // 我们需要分配/释放物理内存（粒度为 4KB 或其他大小）。
    // 因此在 pmm.h 中定义了物理内存管理器的框架（struct pmm_manager）。
    // 首先，我们应该基于该框架初始化一个物理内存管理器(pmm)。
    // 然后 pmm 可以分配/释放物理内存。
    // 现在，first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。
    init_pmm_manager();// 初始化物理内存管理器
c01055f0:	e8 8e f9 ff ff       	call   c0104f83 <init_pmm_manager>

    // detect physical memory space, reserve already used memory,
    // then use pmm->init_memmap to create free page list
    // 检测物理内存空间，保留已经使用的内存，
    // 然后使用 pmm->init_memmap 创建空闲页面列表
    page_init();// 初始化页面管理
c01055f5:	e8 b0 fa ff ff       	call   c01050aa <page_init>

    //use pmm->check to verify the correctness of the alloc/free function in a pmm
    // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性
    check_alloc_page();// 检查页面分配功能
c01055fa:	e8 bf 04 00 00       	call   c0105abe <check_alloc_page>

    check_pgdir();// 检查页目录的状态
c01055ff:	e8 db 04 00 00       	call   c0105adf <check_pgdir>

    // recursively insert boot_pgdir in itself
    // to form a virtual page table at virtual address VPT
    // 递归地将 boot_pgdir 插入到自身中
    // 在虚拟地址 VPT 处形成虚拟页表
    boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W;// 设置页目录项，映射自身
c0105604:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105609:	89 45 f0             	mov    %eax,-0x10(%ebp)
c010560c:	81 7d f0 ff ff ff bf 	cmpl   $0xbfffffff,-0x10(%ebp)
c0105613:	77 23                	ja     c0105638 <pmm_init+0x8f>
c0105615:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105618:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010561c:	c7 44 24 08 e0 ae 10 	movl   $0xc010aee0,0x8(%esp)
c0105623:	c0 
c0105624:	c7 44 24 04 83 01 00 	movl   $0x183,0x4(%esp)
c010562b:	00 
c010562c:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105633:	e8 0d b6 ff ff       	call   c0100c45 <__panic>
c0105638:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010563b:	8d 90 00 00 00 40    	lea    0x40000000(%eax),%edx
c0105641:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105646:	05 ac 0f 00 00       	add    $0xfac,%eax
c010564b:	83 ca 03             	or     $0x3,%edx
c010564e:	89 10                	mov    %edx,(%eax)

    // map all physical memory to linear memory with base linear addr KERNBASE
    // linear_addr KERNBASE ~ KERNBASE + KMEMSIZE = phy_addr 0 ~ KMEMSIZE
    // 将所有物理内存映射到线性内存，基地址为 KERNBASE
    // 线性地址 KERNBASE ~ KERNBASE + KMEMSIZE = 物理地址 0 ~ KMEMSIZE
    boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W);// 映射物理内存
c0105650:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105655:	c7 44 24 10 02 00 00 	movl   $0x2,0x10(%esp)
c010565c:	00 
c010565d:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0105664:	00 
c0105665:	c7 44 24 08 00 00 00 	movl   $0x38000000,0x8(%esp)
c010566c:	38 
c010566d:	c7 44 24 04 00 00 00 	movl   $0xc0000000,0x4(%esp)
c0105674:	c0 
c0105675:	89 04 24             	mov    %eax,(%esp)
c0105678:	e8 e0 fd ff ff       	call   c010545d <boot_map_segment>
    // then set kernel stack (ss:esp) in TSS, setup TSS in gdt, load TSS
    // 由于我们正在使用引导加载程序的 GDT，
    // 我们应该重新加载 GDT（第二次，也是最后一次），以获取用户段和 TSS
    // 映射虚拟地址 0 ~ 4G = 线性地址 0 ~ 4G
    // 然后在 TSS 中设置内核栈 (ss:esp)，在 gdt 中设置 TSS，加载 TSS
    gdt_init();// 初始化全局描述符表
c010567d:	e8 15 f8 ff ff       	call   c0104e97 <gdt_init>

    //now the basic virtual memory map(see memalyout.h) is established.
    //check the correctness of the basic virtual memory map.
     // 现在基本的虚拟内存映射（见 memlayout.h）已建立。
    // 检查基础虚拟内存映射的正确性。
    check_boot_pgdir(); // 检查页目录的正确性
c0105682:	e8 f6 0a 00 00       	call   c010617d <check_boot_pgdir>

    print_pgdir(); // 打印页目录表
c0105687:	e8 73 0f 00 00       	call   c01065ff <print_pgdir>
    kmalloc_init();
c010568c:	e8 70 f3 ff ff       	call   c0104a01 <kmalloc_init>

}
c0105691:	90                   	nop
c0105692:	89 ec                	mov    %ebp,%esp
c0105694:	5d                   	pop    %ebp
c0105695:	c3                   	ret    

c0105696 <get_pte>:
//  pgdir:  页目录的内核虚拟基地址
//  la:     需要映射的线性地址
//  create: 一个逻辑值，决定是否为页表分配一页
// 返回值：该 PTE 的内核虚拟地址
pte_t *
get_pte(pde_t *pgdir, uintptr_t la, bool create) {
c0105696:	55                   	push   %ebp
c0105697:	89 e5                	mov    %esp,%ebp
c0105699:	83 ec 38             	sub    $0x38,%esp
                          // (7) set page directory entry's permission
    }
    return NULL;          // (8) return page table entry
#endif
    // (1) 找到页目录项
    pde_t *pdep = &pgdir[PDX(la)];// 使用 PDX 宏获取页目录索引
c010569c:	8b 45 0c             	mov    0xc(%ebp),%eax
c010569f:	c1 e8 16             	shr    $0x16,%eax
c01056a2:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c01056a9:	8b 45 08             	mov    0x8(%ebp),%eax
c01056ac:	01 d0                	add    %edx,%eax
c01056ae:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // (2) 检查页目录项是否存在
    if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置
c01056b1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01056b4:	8b 00                	mov    (%eax),%eax
c01056b6:	83 e0 01             	and    $0x1,%eax
c01056b9:	85 c0                	test   %eax,%eax
c01056bb:	0f 85 af 00 00 00    	jne    c0105770 <get_pte+0xda>
        struct Page *page;// 声明一个指针，用于指向新分配的页面
        // 检查是否允许创建新页表，或者分配页表失败
        if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败
c01056c1:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c01056c5:	74 15                	je     c01056dc <get_pte+0x46>
c01056c7:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01056ce:	e8 08 f9 ff ff       	call   c0104fdb <alloc_pages>
c01056d3:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01056d6:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01056da:	75 0a                	jne    c01056e6 <get_pte+0x50>
            return NULL;// 返回 NULL，表示无法获取页表
c01056dc:	b8 00 00 00 00       	mov    $0x0,%eax
c01056e1:	e9 e7 00 00 00       	jmp    c01057cd <get_pte+0x137>
        }
        // 设置新分配页面的引用计数为 1
        set_page_ref(page, 1);
c01056e6:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01056ed:	00 
c01056ee:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01056f1:	89 04 24             	mov    %eax,(%esp)
c01056f4:	e8 dc f6 ff ff       	call   c0104dd5 <set_page_ref>
        uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址
c01056f9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01056fc:	89 04 24             	mov    %eax,(%esp)
c01056ff:	e8 b7 f5 ff ff       	call   c0104cbb <page2pa>
c0105704:	89 45 ec             	mov    %eax,-0x14(%ebp)
        memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容，初始化为零
c0105707:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010570a:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010570d:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105710:	c1 e8 0c             	shr    $0xc,%eax
c0105713:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0105716:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c010571b:	39 45 e4             	cmp    %eax,-0x1c(%ebp)
c010571e:	72 23                	jb     c0105743 <get_pte+0xad>
c0105720:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105723:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0105727:	c7 44 24 08 3c ae 10 	movl   $0xc010ae3c,0x8(%esp)
c010572e:	c0 
c010572f:	c7 44 24 04 dd 01 00 	movl   $0x1dd,0x4(%esp)
c0105736:	00 
c0105737:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c010573e:	e8 02 b5 ff ff       	call   c0100c45 <__panic>
c0105743:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0105746:	2d 00 00 00 40       	sub    $0x40000000,%eax
c010574b:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c0105752:	00 
c0105753:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c010575a:	00 
c010575b:	89 04 24             	mov    %eax,(%esp)
c010575e:	e8 81 47 00 00       	call   c0109ee4 <memset>
        // 更新页目录项，设置物理地址和权限位
        *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位（用户可访问、可写、有效）合并设置
c0105763:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0105766:	83 c8 07             	or     $0x7,%eax
c0105769:	89 c2                	mov    %eax,%edx
c010576b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010576e:	89 10                	mov    %edx,(%eax)
    }
    // 返回指定线性地址 la 对应的页表项的内核虚拟地址
    return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针
c0105770:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105773:	8b 00                	mov    (%eax),%eax
c0105775:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c010577a:	89 45 e0             	mov    %eax,-0x20(%ebp)
c010577d:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0105780:	c1 e8 0c             	shr    $0xc,%eax
c0105783:	89 45 dc             	mov    %eax,-0x24(%ebp)
c0105786:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c010578b:	39 45 dc             	cmp    %eax,-0x24(%ebp)
c010578e:	72 23                	jb     c01057b3 <get_pte+0x11d>
c0105790:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0105793:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0105797:	c7 44 24 08 3c ae 10 	movl   $0xc010ae3c,0x8(%esp)
c010579e:	c0 
c010579f:	c7 44 24 04 e2 01 00 	movl   $0x1e2,0x4(%esp)
c01057a6:	00 
c01057a7:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01057ae:	e8 92 b4 ff ff       	call   c0100c45 <__panic>
c01057b3:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01057b6:	2d 00 00 00 40       	sub    $0x40000000,%eax
c01057bb:	89 c2                	mov    %eax,%edx
c01057bd:	8b 45 0c             	mov    0xc(%ebp),%eax
c01057c0:	c1 e8 0c             	shr    $0xc,%eax
c01057c3:	25 ff 03 00 00       	and    $0x3ff,%eax
c01057c8:	c1 e0 02             	shl    $0x2,%eax
c01057cb:	01 d0                	add    %edx,%eax
}
c01057cd:	89 ec                	mov    %ebp,%esp
c01057cf:	5d                   	pop    %ebp
c01057d0:	c3                   	ret    

c01057d1 <get_page>:

//get_page - get related Page struct for linear address la using PDT pgdir
// get_page - 获取与线性地址 la 相关的 Page 结构体，使用页目录 pgdir
struct Page *
get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store) {
c01057d1:	55                   	push   %ebp
c01057d2:	89 e5                	mov    %esp,%ebp
c01057d4:	83 ec 28             	sub    $0x28,%esp
     // 调用 get_pte 函数获取对应线性地址 la 的页表项指针
    pte_t *ptep = get_pte(pgdir, la, 0);
c01057d7:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01057de:	00 
c01057df:	8b 45 0c             	mov    0xc(%ebp),%eax
c01057e2:	89 44 24 04          	mov    %eax,0x4(%esp)
c01057e6:	8b 45 08             	mov    0x8(%ebp),%eax
c01057e9:	89 04 24             	mov    %eax,(%esp)
c01057ec:	e8 a5 fe ff ff       	call   c0105696 <get_pte>
c01057f1:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 如果 ptep_store 指针不为 NULL，将 ptep 存储到 ptep_store 指向的位置
    if (ptep_store != NULL) {
c01057f4:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c01057f8:	74 08                	je     c0105802 <get_page+0x31>
        *ptep_store = ptep; // 存储当前页表项的指针
c01057fa:	8b 45 10             	mov    0x10(%ebp),%eax
c01057fd:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105800:	89 10                	mov    %edx,(%eax)
    }
    // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置
    if (ptep != NULL && *ptep & PTE_P) {
c0105802:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105806:	74 1b                	je     c0105823 <get_page+0x52>
c0105808:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010580b:	8b 00                	mov    (%eax),%eax
c010580d:	83 e0 01             	and    $0x1,%eax
c0105810:	85 c0                	test   %eax,%eax
c0105812:	74 0f                	je     c0105823 <get_page+0x52>
        // 返回与页表项对应的 Page 结构体
        return pte2page(*ptep);// 将页表项转换为对应的 Page 结构
c0105814:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105817:	8b 00                	mov    (%eax),%eax
c0105819:	89 04 24             	mov    %eax,(%esp)
c010581c:	e8 50 f5 ff ff       	call   c0104d71 <pte2page>
c0105821:	eb 05                	jmp    c0105828 <get_page+0x57>
    }
    // 如果未找到有效的页，返回 NULL
    return NULL;
c0105823:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0105828:	89 ec                	mov    %ebp,%esp
c010582a:	5d                   	pop    %ebp
c010582b:	c3                   	ret    

c010582c <page_remove_pte>:

//page_remove_pte - free an Page sturct which is related linear address la
//                - and clean(invalidate) pte which is related linear address la
//note: PT is changed, so the TLB need to be invalidate 
static inline void
page_remove_pte(pde_t *pgdir, uintptr_t la, pte_t *ptep) {
c010582c:	55                   	push   %ebp
c010582d:	89 e5                	mov    %esp,%ebp
c010582f:	83 ec 28             	sub    $0x28,%esp
                                  //(4) and free this page when page reference reachs 0
                                  //(5) clear second page table entry
                                  //(6) flush tlb
    }
#endif
    if (*ptep & PTE_P) {
c0105832:	8b 45 10             	mov    0x10(%ebp),%eax
c0105835:	8b 00                	mov    (%eax),%eax
c0105837:	83 e0 01             	and    $0x1,%eax
c010583a:	85 c0                	test   %eax,%eax
c010583c:	74 4d                	je     c010588b <page_remove_pte+0x5f>
        struct Page *page = pte2page(*ptep);// 找到对应的物理页
c010583e:	8b 45 10             	mov    0x10(%ebp),%eax
c0105841:	8b 00                	mov    (%eax),%eax
c0105843:	89 04 24             	mov    %eax,(%esp)
c0105846:	e8 26 f5 ff ff       	call   c0104d71 <pte2page>
c010584b:	89 45 f4             	mov    %eax,-0xc(%ebp)
        // 减少物理页的引用计数，如果引用计数为零，释放该物理页
        if (page_ref_dec(page) == 0) {
c010584e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105851:	89 04 24             	mov    %eax,(%esp)
c0105854:	e8 a1 f5 ff ff       	call   c0104dfa <page_ref_dec>
c0105859:	85 c0                	test   %eax,%eax
c010585b:	75 13                	jne    c0105870 <page_remove_pte+0x44>
            free_page(page);
c010585d:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0105864:	00 
c0105865:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105868:	89 04 24             	mov    %eax,(%esp)
c010586b:	e8 d8 f7 ff ff       	call   c0105048 <free_pages>
        }
        *ptep = 0;// 清除页表项
c0105870:	8b 45 10             	mov    0x10(%ebp),%eax
c0105873:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
        tlb_invalidate(pgdir, la);// 刷新 TLB
c0105879:	8b 45 0c             	mov    0xc(%ebp),%eax
c010587c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105880:	8b 45 08             	mov    0x8(%ebp),%eax
c0105883:	89 04 24             	mov    %eax,(%esp)
c0105886:	e8 07 01 00 00       	call   c0105992 <tlb_invalidate>
    }
}
c010588b:	90                   	nop
c010588c:	89 ec                	mov    %ebp,%esp
c010588e:	5d                   	pop    %ebp
c010588f:	c3                   	ret    

c0105890 <page_remove>:

//page_remove - free an Page which is related linear address la and has an validated pte
//移除一个虚拟地址对应的页面
void
page_remove(pde_t *pgdir, uintptr_t la) {
c0105890:	55                   	push   %ebp
c0105891:	89 e5                	mov    %esp,%ebp
c0105893:	83 ec 28             	sub    $0x28,%esp
    //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。
    pte_t *ptep = get_pte(pgdir, la, 0);
c0105896:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c010589d:	00 
c010589e:	8b 45 0c             	mov    0xc(%ebp),%eax
c01058a1:	89 44 24 04          	mov    %eax,0x4(%esp)
c01058a5:	8b 45 08             	mov    0x8(%ebp),%eax
c01058a8:	89 04 24             	mov    %eax,(%esp)
c01058ab:	e8 e6 fd ff ff       	call   c0105696 <get_pte>
c01058b0:	89 45 f4             	mov    %eax,-0xc(%ebp)
    //如果 ptep 不为 NULL，则调用 page_remove_pte 函数移除该页表项。
    if (ptep != NULL) {
c01058b3:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01058b7:	74 19                	je     c01058d2 <page_remove+0x42>
        page_remove_pte(pgdir, la, ptep);
c01058b9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01058bc:	89 44 24 08          	mov    %eax,0x8(%esp)
c01058c0:	8b 45 0c             	mov    0xc(%ebp),%eax
c01058c3:	89 44 24 04          	mov    %eax,0x4(%esp)
c01058c7:	8b 45 08             	mov    0x8(%ebp),%eax
c01058ca:	89 04 24             	mov    %eax,(%esp)
c01058cd:	e8 5a ff ff ff       	call   c010582c <page_remove_pte>
    }
}
c01058d2:	90                   	nop
c01058d3:	89 ec                	mov    %ebp,%esp
c01058d5:	5d                   	pop    %ebp
c01058d6:	c3                   	ret    

c01058d7 <page_insert>:
//  perm:  the permission of this Page which is setted in related pte
// return value: always 0
//note: PT is changed, so the TLB need to be invalidate 
//将一个页面插入到页表中。
int
page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm) {
c01058d7:	55                   	push   %ebp
c01058d8:	89 e5                	mov    %esp,%ebp
c01058da:	83 ec 28             	sub    $0x28,%esp
    //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。
    pte_t *ptep = get_pte(pgdir, la, 1);
c01058dd:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c01058e4:	00 
c01058e5:	8b 45 10             	mov    0x10(%ebp),%eax
c01058e8:	89 44 24 04          	mov    %eax,0x4(%esp)
c01058ec:	8b 45 08             	mov    0x8(%ebp),%eax
c01058ef:	89 04 24             	mov    %eax,(%esp)
c01058f2:	e8 9f fd ff ff       	call   c0105696 <get_pte>
c01058f7:	89 45 f4             	mov    %eax,-0xc(%ebp)
    //如果 ptep 为 NULL，表示内存分配失败，返回 -E_NO_MEM。
    if (ptep == NULL) {
c01058fa:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01058fe:	75 0a                	jne    c010590a <page_insert+0x33>
        return -E_NO_MEM;
c0105900:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
c0105905:	e9 84 00 00 00       	jmp    c010598e <page_insert+0xb7>
    }
    //调用 page_ref_inc 增加页面的引用计数。
    page_ref_inc(page);
c010590a:	8b 45 0c             	mov    0xc(%ebp),%eax
c010590d:	89 04 24             	mov    %eax,(%esp)
c0105910:	e8 ce f4 ff ff       	call   c0104de3 <page_ref_inc>
    //如果页表项已存在且指向当前页面，则减少页面引用计数。
    if (*ptep & PTE_P) {
c0105915:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105918:	8b 00                	mov    (%eax),%eax
c010591a:	83 e0 01             	and    $0x1,%eax
c010591d:	85 c0                	test   %eax,%eax
c010591f:	74 3e                	je     c010595f <page_insert+0x88>
        struct Page *p = pte2page(*ptep);
c0105921:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105924:	8b 00                	mov    (%eax),%eax
c0105926:	89 04 24             	mov    %eax,(%esp)
c0105929:	e8 43 f4 ff ff       	call   c0104d71 <pte2page>
c010592e:	89 45 f0             	mov    %eax,-0x10(%ebp)
        if (p == page) {
c0105931:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105934:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0105937:	75 0d                	jne    c0105946 <page_insert+0x6f>
            page_ref_dec(page);
c0105939:	8b 45 0c             	mov    0xc(%ebp),%eax
c010593c:	89 04 24             	mov    %eax,(%esp)
c010593f:	e8 b6 f4 ff ff       	call   c0104dfa <page_ref_dec>
c0105944:	eb 19                	jmp    c010595f <page_insert+0x88>
        }
        //如果页表项已存在但指向其他页面，则调用 page_remove_pte 移除旧的页表项。
        else {
            page_remove_pte(pgdir, la, ptep);
c0105946:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105949:	89 44 24 08          	mov    %eax,0x8(%esp)
c010594d:	8b 45 10             	mov    0x10(%ebp),%eax
c0105950:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105954:	8b 45 08             	mov    0x8(%ebp),%eax
c0105957:	89 04 24             	mov    %eax,(%esp)
c010595a:	e8 cd fe ff ff       	call   c010582c <page_remove_pte>
        }
    }
    *ptep = page2pa(page) | PTE_P | perm;
c010595f:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105962:	89 04 24             	mov    %eax,(%esp)
c0105965:	e8 51 f3 ff ff       	call   c0104cbb <page2pa>
c010596a:	0b 45 14             	or     0x14(%ebp),%eax
c010596d:	83 c8 01             	or     $0x1,%eax
c0105970:	89 c2                	mov    %eax,%edx
c0105972:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105975:	89 10                	mov    %edx,(%eax)
    tlb_invalidate(pgdir, la);//刷新 TLB
c0105977:	8b 45 10             	mov    0x10(%ebp),%eax
c010597a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010597e:	8b 45 08             	mov    0x8(%ebp),%eax
c0105981:	89 04 24             	mov    %eax,(%esp)
c0105984:	e8 09 00 00 00       	call   c0105992 <tlb_invalidate>
    return 0;
c0105989:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010598e:	89 ec                	mov    %ebp,%esp
c0105990:	5d                   	pop    %ebp
c0105991:	c3                   	ret    

c0105992 <tlb_invalidate>:

// invalidate a TLB entry, but only if the page tables being
// edited are the ones currently in use by the processor.
//无效化指定地址的TLB条目
void
tlb_invalidate(pde_t *pgdir, uintptr_t la) {
c0105992:	55                   	push   %ebp
c0105993:	89 e5                	mov    %esp,%ebp
c0105995:	83 ec 28             	sub    $0x28,%esp
}

static inline uintptr_t
rcr3(void) {
    uintptr_t cr3;
    asm volatile ("mov %%cr3, %0" : "=r" (cr3) :: "memory");
c0105998:	0f 20 d8             	mov    %cr3,%eax
c010599b:	89 45 f0             	mov    %eax,-0x10(%ebp)
    return cr3;
c010599e:	8b 55 f0             	mov    -0x10(%ebp),%edx
    //检查当前页目录地址是否与传入的页目录地址相同。
    if (rcr3() == PADDR(pgdir)) {
c01059a1:	8b 45 08             	mov    0x8(%ebp),%eax
c01059a4:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01059a7:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c01059ae:	77 23                	ja     c01059d3 <tlb_invalidate+0x41>
c01059b0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01059b3:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01059b7:	c7 44 24 08 e0 ae 10 	movl   $0xc010aee0,0x8(%esp)
c01059be:	c0 
c01059bf:	c7 44 24 04 56 02 00 	movl   $0x256,0x4(%esp)
c01059c6:	00 
c01059c7:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01059ce:	e8 72 b2 ff ff       	call   c0100c45 <__panic>
c01059d3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01059d6:	05 00 00 00 40       	add    $0x40000000,%eax
c01059db:	39 d0                	cmp    %edx,%eax
c01059dd:	75 0d                	jne    c01059ec <tlb_invalidate+0x5a>
        //如果相同，则调用 invlpg 函数无效化指定线性地址的TLB条目。
        invlpg((void *)la);
c01059df:	8b 45 0c             	mov    0xc(%ebp),%eax
c01059e2:	89 45 ec             	mov    %eax,-0x14(%ebp)
}

static inline void
invlpg(void *addr) {
    asm volatile ("invlpg (%0)" :: "r" (addr) : "memory");
c01059e5:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01059e8:	0f 01 38             	invlpg (%eax)
}
c01059eb:	90                   	nop
    }
}
c01059ec:	90                   	nop
c01059ed:	89 ec                	mov    %ebp,%esp
c01059ef:	5d                   	pop    %ebp
c01059f0:	c3                   	ret    

c01059f1 <pgdir_alloc_page>:
// pgdir_alloc_page - call alloc_page & page_insert functions to 
//                  - allocate a page size memory & setup an addr map
//                  - pa<->la with linear address la and the PDT pgdir
//参数包括页目录指针 pgdir、线性地址 la 和权限 perm。
struct Page *
pgdir_alloc_page(pde_t *pgdir, uintptr_t la, uint32_t perm) {
c01059f1:	55                   	push   %ebp
c01059f2:	89 e5                	mov    %esp,%ebp
c01059f4:	83 ec 28             	sub    $0x28,%esp
    struct Page *page = alloc_page();//分配一个新的页面存储在 page 指针中
c01059f7:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01059fe:	e8 d8 f5 ff ff       	call   c0104fdb <alloc_pages>
c0105a03:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (page != NULL) {//检查 page 是否不为 NULL，即分配是否成功。
c0105a06:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0105a0a:	0f 84 a7 00 00 00    	je     c0105ab7 <pgdir_alloc_page+0xc6>
        if (page_insert(pgdir, page, la, perm) != 0) {//将页面插入到指定的线性地址 la 处。
c0105a10:	8b 45 10             	mov    0x10(%ebp),%eax
c0105a13:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0105a17:	8b 45 0c             	mov    0xc(%ebp),%eax
c0105a1a:	89 44 24 08          	mov    %eax,0x8(%esp)
c0105a1e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105a21:	89 44 24 04          	mov    %eax,0x4(%esp)
c0105a25:	8b 45 08             	mov    0x8(%ebp),%eax
c0105a28:	89 04 24             	mov    %eax,(%esp)
c0105a2b:	e8 a7 fe ff ff       	call   c01058d7 <page_insert>
c0105a30:	85 c0                	test   %eax,%eax
c0105a32:	74 1a                	je     c0105a4e <pgdir_alloc_page+0x5d>
            free_page(page);//释放分配的页面。
c0105a34:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0105a3b:	00 
c0105a3c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105a3f:	89 04 24             	mov    %eax,(%esp)
c0105a42:	e8 01 f6 ff ff       	call   c0105048 <free_pages>
            return NULL;//返回 NULL，表示页面插入失败。
c0105a47:	b8 00 00 00 00       	mov    $0x0,%eax
c0105a4c:	eb 6c                	jmp    c0105aba <pgdir_alloc_page+0xc9>
        }
        if (swap_init_ok){//检查交换区是否已初始化成功
c0105a4e:	a1 a4 c0 12 c0       	mov    0xc012c0a4,%eax
c0105a53:	85 c0                	test   %eax,%eax
c0105a55:	74 60                	je     c0105ab7 <pgdir_alloc_page+0xc6>
            //将页面映射到交换区。
            swap_map_swappable(check_mm_struct, la, page, 0);
c0105a57:	a1 6c c1 12 c0       	mov    0xc012c16c,%eax
c0105a5c:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0105a63:	00 
c0105a64:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105a67:	89 54 24 08          	mov    %edx,0x8(%esp)
c0105a6b:	8b 55 0c             	mov    0xc(%ebp),%edx
c0105a6e:	89 54 24 04          	mov    %edx,0x4(%esp)
c0105a72:	89 04 24             	mov    %eax,(%esp)
c0105a75:	e8 3a 0e 00 00       	call   c01068b4 <swap_map_swappable>
            //设置页面的虚拟地址 pra_vaddr 为 la
            page->pra_vaddr=la;
c0105a7a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105a7d:	8b 55 0c             	mov    0xc(%ebp),%edx
c0105a80:	89 50 1c             	mov    %edx,0x1c(%eax)
            //断言页面的引用计数为1，确保页面没有被其他地方引用。
            assert(page_ref(page) == 1);
c0105a83:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105a86:	89 04 24             	mov    %eax,(%esp)
c0105a89:	e8 3d f3 ff ff       	call   c0104dcb <page_ref>
c0105a8e:	83 f8 01             	cmp    $0x1,%eax
c0105a91:	74 24                	je     c0105ab7 <pgdir_alloc_page+0xc6>
c0105a93:	c7 44 24 0c 64 af 10 	movl   $0xc010af64,0xc(%esp)
c0105a9a:	c0 
c0105a9b:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105aa2:	c0 
c0105aa3:	c7 44 24 04 6e 02 00 	movl   $0x26e,0x4(%esp)
c0105aaa:	00 
c0105aab:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105ab2:	e8 8e b1 ff ff       	call   c0100c45 <__panic>
            //cprintf("get No. %d  page: pra_vaddr %x, pra_link.prev %x, pra_link_next %x in pgdir_alloc_page\n", (page-pages), page->pra_vaddr,page->pra_page_link.prev, page->pra_page_link.next);
        }

    }

    return page;
c0105ab7:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0105aba:	89 ec                	mov    %ebp,%esp
c0105abc:	5d                   	pop    %ebp
c0105abd:	c3                   	ret    

c0105abe <check_alloc_page>:

static void
check_alloc_page(void) {
c0105abe:	55                   	push   %ebp
c0105abf:	89 e5                	mov    %esp,%ebp
c0105ac1:	83 ec 18             	sub    $0x18,%esp
    //调用内存管理器的 check 方法，用于检查内存分配是否正常。
    pmm_manager->check();
c0105ac4:	a1 0c c0 12 c0       	mov    0xc012c00c,%eax
c0105ac9:	8b 40 18             	mov    0x18(%eax),%eax
c0105acc:	ff d0                	call   *%eax
    cprintf("check_alloc_page() succeeded!\n");
c0105ace:	c7 04 24 78 af 10 c0 	movl   $0xc010af78,(%esp)
c0105ad5:	e8 9e a8 ff ff       	call   c0100378 <cprintf>
}
c0105ada:	90                   	nop
c0105adb:	89 ec                	mov    %ebp,%esp
c0105add:	5d                   	pop    %ebp
c0105ade:	c3                   	ret    

c0105adf <check_pgdir>:

//用于验证页目录和页表的正确性。
static void
check_pgdir(void) {
c0105adf:	55                   	push   %ebp
c0105ae0:	89 e5                	mov    %esp,%ebp
c0105ae2:	83 ec 38             	sub    $0x38,%esp
    //确保内存页面数量在合理范围内
    assert(npage <= KMEMSIZE / PGSIZE);
c0105ae5:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c0105aea:	3d 00 80 03 00       	cmp    $0x38000,%eax
c0105aef:	76 24                	jbe    c0105b15 <check_pgdir+0x36>
c0105af1:	c7 44 24 0c 97 af 10 	movl   $0xc010af97,0xc(%esp)
c0105af8:	c0 
c0105af9:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105b00:	c0 
c0105b01:	c7 44 24 04 82 02 00 	movl   $0x282,0x4(%esp)
c0105b08:	00 
c0105b09:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105b10:	e8 30 b1 ff ff       	call   c0100c45 <__panic>
    //确保页目录不为空且对齐，
    assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0);
c0105b15:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105b1a:	85 c0                	test   %eax,%eax
c0105b1c:	74 0e                	je     c0105b2c <check_pgdir+0x4d>
c0105b1e:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105b23:	25 ff 0f 00 00       	and    $0xfff,%eax
c0105b28:	85 c0                	test   %eax,%eax
c0105b2a:	74 24                	je     c0105b50 <check_pgdir+0x71>
c0105b2c:	c7 44 24 0c b4 af 10 	movl   $0xc010afb4,0xc(%esp)
c0105b33:	c0 
c0105b34:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105b3b:	c0 
c0105b3c:	c7 44 24 04 84 02 00 	movl   $0x284,0x4(%esp)
c0105b43:	00 
c0105b44:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105b4b:	e8 f5 b0 ff ff       	call   c0100c45 <__panic>
    //确保虚拟地址 0x0 没有映射任何页面
    assert(get_page(boot_pgdir, 0x0, NULL) == NULL);
c0105b50:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105b55:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105b5c:	00 
c0105b5d:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0105b64:	00 
c0105b65:	89 04 24             	mov    %eax,(%esp)
c0105b68:	e8 64 fc ff ff       	call   c01057d1 <get_page>
c0105b6d:	85 c0                	test   %eax,%eax
c0105b6f:	74 24                	je     c0105b95 <check_pgdir+0xb6>
c0105b71:	c7 44 24 0c ec af 10 	movl   $0xc010afec,0xc(%esp)
c0105b78:	c0 
c0105b79:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105b80:	c0 
c0105b81:	c7 44 24 04 86 02 00 	movl   $0x286,0x4(%esp)
c0105b88:	00 
c0105b89:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105b90:	e8 b0 b0 ff ff       	call   c0100c45 <__panic>
    
    //定义两个页面指针 p1 和 p2
    struct Page *p1, *p2;
    //分配一个页面 p1
    p1 = alloc_page();
c0105b95:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0105b9c:	e8 3a f4 ff ff       	call   c0104fdb <alloc_pages>
c0105ba1:	89 45 f4             	mov    %eax,-0xc(%ebp)
    //将 p1 插入到虚拟地址 0x0
    assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0);
c0105ba4:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105ba9:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0105bb0:	00 
c0105bb1:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105bb8:	00 
c0105bb9:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105bbc:	89 54 24 04          	mov    %edx,0x4(%esp)
c0105bc0:	89 04 24             	mov    %eax,(%esp)
c0105bc3:	e8 0f fd ff ff       	call   c01058d7 <page_insert>
c0105bc8:	85 c0                	test   %eax,%eax
c0105bca:	74 24                	je     c0105bf0 <check_pgdir+0x111>
c0105bcc:	c7 44 24 0c 14 b0 10 	movl   $0xc010b014,0xc(%esp)
c0105bd3:	c0 
c0105bd4:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105bdb:	c0 
c0105bdc:	c7 44 24 04 8d 02 00 	movl   $0x28d,0x4(%esp)
c0105be3:	00 
c0105be4:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105beb:	e8 55 b0 ff ff       	call   c0100c45 <__panic>

    // 获取虚拟地址 0x0 对应的页表项指针
    pte_t *ptep;
    assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL);
c0105bf0:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105bf5:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105bfc:	00 
c0105bfd:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0105c04:	00 
c0105c05:	89 04 24             	mov    %eax,(%esp)
c0105c08:	e8 89 fa ff ff       	call   c0105696 <get_pte>
c0105c0d:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0105c10:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0105c14:	75 24                	jne    c0105c3a <check_pgdir+0x15b>
c0105c16:	c7 44 24 0c 40 b0 10 	movl   $0xc010b040,0xc(%esp)
c0105c1d:	c0 
c0105c1e:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105c25:	c0 
c0105c26:	c7 44 24 04 91 02 00 	movl   $0x291,0x4(%esp)
c0105c2d:	00 
c0105c2e:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105c35:	e8 0b b0 ff ff       	call   c0100c45 <__panic>
    // 验证页表项对应的页面是 p1
    assert(pte2page(*ptep) == p1);
c0105c3a:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105c3d:	8b 00                	mov    (%eax),%eax
c0105c3f:	89 04 24             	mov    %eax,(%esp)
c0105c42:	e8 2a f1 ff ff       	call   c0104d71 <pte2page>
c0105c47:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0105c4a:	74 24                	je     c0105c70 <check_pgdir+0x191>
c0105c4c:	c7 44 24 0c 6d b0 10 	movl   $0xc010b06d,0xc(%esp)
c0105c53:	c0 
c0105c54:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105c5b:	c0 
c0105c5c:	c7 44 24 04 93 02 00 	movl   $0x293,0x4(%esp)
c0105c63:	00 
c0105c64:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105c6b:	e8 d5 af ff ff       	call   c0100c45 <__panic>
    // 验证 p1 的引用计数为 1
    assert(page_ref(p1) == 1);
c0105c70:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105c73:	89 04 24             	mov    %eax,(%esp)
c0105c76:	e8 50 f1 ff ff       	call   c0104dcb <page_ref>
c0105c7b:	83 f8 01             	cmp    $0x1,%eax
c0105c7e:	74 24                	je     c0105ca4 <check_pgdir+0x1c5>
c0105c80:	c7 44 24 0c 83 b0 10 	movl   $0xc010b083,0xc(%esp)
c0105c87:	c0 
c0105c88:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105c8f:	c0 
c0105c90:	c7 44 24 04 95 02 00 	movl   $0x295,0x4(%esp)
c0105c97:	00 
c0105c98:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105c9f:	e8 a1 af ff ff       	call   c0100c45 <__panic>
    // 获取虚拟地址 PGSIZE 对应的页表项指针
    ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1];
c0105ca4:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105ca9:	8b 00                	mov    (%eax),%eax
c0105cab:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0105cb0:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0105cb3:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0105cb6:	c1 e8 0c             	shr    $0xc,%eax
c0105cb9:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0105cbc:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c0105cc1:	39 45 e8             	cmp    %eax,-0x18(%ebp)
c0105cc4:	72 23                	jb     c0105ce9 <check_pgdir+0x20a>
c0105cc6:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0105cc9:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0105ccd:	c7 44 24 08 3c ae 10 	movl   $0xc010ae3c,0x8(%esp)
c0105cd4:	c0 
c0105cd5:	c7 44 24 04 97 02 00 	movl   $0x297,0x4(%esp)
c0105cdc:	00 
c0105cdd:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105ce4:	e8 5c af ff ff       	call   c0100c45 <__panic>
c0105ce9:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0105cec:	2d 00 00 00 40       	sub    $0x40000000,%eax
c0105cf1:	83 c0 04             	add    $0x4,%eax
c0105cf4:	89 45 f0             	mov    %eax,-0x10(%ebp)
    assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep);
c0105cf7:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105cfc:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105d03:	00 
c0105d04:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0105d0b:	00 
c0105d0c:	89 04 24             	mov    %eax,(%esp)
c0105d0f:	e8 82 f9 ff ff       	call   c0105696 <get_pte>
c0105d14:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0105d17:	74 24                	je     c0105d3d <check_pgdir+0x25e>
c0105d19:	c7 44 24 0c 98 b0 10 	movl   $0xc010b098,0xc(%esp)
c0105d20:	c0 
c0105d21:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105d28:	c0 
c0105d29:	c7 44 24 04 98 02 00 	movl   $0x298,0x4(%esp)
c0105d30:	00 
c0105d31:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105d38:	e8 08 af ff ff       	call   c0100c45 <__panic>
    // 分配一个页面 p2
    p2 = alloc_page();
c0105d3d:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0105d44:	e8 92 f2 ff ff       	call   c0104fdb <alloc_pages>
c0105d49:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    // 将 p2 插入到虚拟地址 PGSIZE，并设置用户和写权限
    assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0);
c0105d4c:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105d51:	c7 44 24 0c 06 00 00 	movl   $0x6,0xc(%esp)
c0105d58:	00 
c0105d59:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c0105d60:	00 
c0105d61:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0105d64:	89 54 24 04          	mov    %edx,0x4(%esp)
c0105d68:	89 04 24             	mov    %eax,(%esp)
c0105d6b:	e8 67 fb ff ff       	call   c01058d7 <page_insert>
c0105d70:	85 c0                	test   %eax,%eax
c0105d72:	74 24                	je     c0105d98 <check_pgdir+0x2b9>
c0105d74:	c7 44 24 0c c0 b0 10 	movl   $0xc010b0c0,0xc(%esp)
c0105d7b:	c0 
c0105d7c:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105d83:	c0 
c0105d84:	c7 44 24 04 9c 02 00 	movl   $0x29c,0x4(%esp)
c0105d8b:	00 
c0105d8c:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105d93:	e8 ad ae ff ff       	call   c0100c45 <__panic>
    // 获取虚拟地址 PGSIZE 对应的页表项指针
    assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL);
c0105d98:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105d9d:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105da4:	00 
c0105da5:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0105dac:	00 
c0105dad:	89 04 24             	mov    %eax,(%esp)
c0105db0:	e8 e1 f8 ff ff       	call   c0105696 <get_pte>
c0105db5:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0105db8:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0105dbc:	75 24                	jne    c0105de2 <check_pgdir+0x303>
c0105dbe:	c7 44 24 0c f8 b0 10 	movl   $0xc010b0f8,0xc(%esp)
c0105dc5:	c0 
c0105dc6:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105dcd:	c0 
c0105dce:	c7 44 24 04 9e 02 00 	movl   $0x29e,0x4(%esp)
c0105dd5:	00 
c0105dd6:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105ddd:	e8 63 ae ff ff       	call   c0100c45 <__panic>
    // 验证页表项设置了用户权限
    assert(*ptep & PTE_U);
c0105de2:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105de5:	8b 00                	mov    (%eax),%eax
c0105de7:	83 e0 04             	and    $0x4,%eax
c0105dea:	85 c0                	test   %eax,%eax
c0105dec:	75 24                	jne    c0105e12 <check_pgdir+0x333>
c0105dee:	c7 44 24 0c 28 b1 10 	movl   $0xc010b128,0xc(%esp)
c0105df5:	c0 
c0105df6:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105dfd:	c0 
c0105dfe:	c7 44 24 04 a0 02 00 	movl   $0x2a0,0x4(%esp)
c0105e05:	00 
c0105e06:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105e0d:	e8 33 ae ff ff       	call   c0100c45 <__panic>
    // 验证页表项设置了写权限
    assert(*ptep & PTE_W);
c0105e12:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105e15:	8b 00                	mov    (%eax),%eax
c0105e17:	83 e0 02             	and    $0x2,%eax
c0105e1a:	85 c0                	test   %eax,%eax
c0105e1c:	75 24                	jne    c0105e42 <check_pgdir+0x363>
c0105e1e:	c7 44 24 0c 36 b1 10 	movl   $0xc010b136,0xc(%esp)
c0105e25:	c0 
c0105e26:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105e2d:	c0 
c0105e2e:	c7 44 24 04 a2 02 00 	movl   $0x2a2,0x4(%esp)
c0105e35:	00 
c0105e36:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105e3d:	e8 03 ae ff ff       	call   c0100c45 <__panic>
    // 验证页目录项设置了用户权限
    assert(boot_pgdir[0] & PTE_U);
c0105e42:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105e47:	8b 00                	mov    (%eax),%eax
c0105e49:	83 e0 04             	and    $0x4,%eax
c0105e4c:	85 c0                	test   %eax,%eax
c0105e4e:	75 24                	jne    c0105e74 <check_pgdir+0x395>
c0105e50:	c7 44 24 0c 44 b1 10 	movl   $0xc010b144,0xc(%esp)
c0105e57:	c0 
c0105e58:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105e5f:	c0 
c0105e60:	c7 44 24 04 a4 02 00 	movl   $0x2a4,0x4(%esp)
c0105e67:	00 
c0105e68:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105e6f:	e8 d1 ad ff ff       	call   c0100c45 <__panic>
    // 验证 p2 的引用计数为 1
    assert(page_ref(p2) == 1);
c0105e74:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0105e77:	89 04 24             	mov    %eax,(%esp)
c0105e7a:	e8 4c ef ff ff       	call   c0104dcb <page_ref>
c0105e7f:	83 f8 01             	cmp    $0x1,%eax
c0105e82:	74 24                	je     c0105ea8 <check_pgdir+0x3c9>
c0105e84:	c7 44 24 0c 5a b1 10 	movl   $0xc010b15a,0xc(%esp)
c0105e8b:	c0 
c0105e8c:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105e93:	c0 
c0105e94:	c7 44 24 04 a6 02 00 	movl   $0x2a6,0x4(%esp)
c0105e9b:	00 
c0105e9c:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105ea3:	e8 9d ad ff ff       	call   c0100c45 <__panic>

    // 将 p1 插入到虚拟地址 PGSIZE，替换掉 p2
    assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0);
c0105ea8:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105ead:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c0105eb4:	00 
c0105eb5:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
c0105ebc:	00 
c0105ebd:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0105ec0:	89 54 24 04          	mov    %edx,0x4(%esp)
c0105ec4:	89 04 24             	mov    %eax,(%esp)
c0105ec7:	e8 0b fa ff ff       	call   c01058d7 <page_insert>
c0105ecc:	85 c0                	test   %eax,%eax
c0105ece:	74 24                	je     c0105ef4 <check_pgdir+0x415>
c0105ed0:	c7 44 24 0c 6c b1 10 	movl   $0xc010b16c,0xc(%esp)
c0105ed7:	c0 
c0105ed8:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105edf:	c0 
c0105ee0:	c7 44 24 04 a9 02 00 	movl   $0x2a9,0x4(%esp)
c0105ee7:	00 
c0105ee8:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105eef:	e8 51 ad ff ff       	call   c0100c45 <__panic>
    // 验证 p1 的引用计数增加到 2
    assert(page_ref(p1) == 2);
c0105ef4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0105ef7:	89 04 24             	mov    %eax,(%esp)
c0105efa:	e8 cc ee ff ff       	call   c0104dcb <page_ref>
c0105eff:	83 f8 02             	cmp    $0x2,%eax
c0105f02:	74 24                	je     c0105f28 <check_pgdir+0x449>
c0105f04:	c7 44 24 0c 98 b1 10 	movl   $0xc010b198,0xc(%esp)
c0105f0b:	c0 
c0105f0c:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105f13:	c0 
c0105f14:	c7 44 24 04 ab 02 00 	movl   $0x2ab,0x4(%esp)
c0105f1b:	00 
c0105f1c:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105f23:	e8 1d ad ff ff       	call   c0100c45 <__panic>
    // 验证 p2 的引用计数减少到 0
    assert(page_ref(p2) == 0);
c0105f28:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0105f2b:	89 04 24             	mov    %eax,(%esp)
c0105f2e:	e8 98 ee ff ff       	call   c0104dcb <page_ref>
c0105f33:	85 c0                	test   %eax,%eax
c0105f35:	74 24                	je     c0105f5b <check_pgdir+0x47c>
c0105f37:	c7 44 24 0c aa b1 10 	movl   $0xc010b1aa,0xc(%esp)
c0105f3e:	c0 
c0105f3f:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105f46:	c0 
c0105f47:	c7 44 24 04 ad 02 00 	movl   $0x2ad,0x4(%esp)
c0105f4e:	00 
c0105f4f:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105f56:	e8 ea ac ff ff       	call   c0100c45 <__panic>
     // 获取虚拟地址 PGSIZE 对应的页表项指针
    assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL);
c0105f5b:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0105f60:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0105f67:	00 
c0105f68:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0105f6f:	00 
c0105f70:	89 04 24             	mov    %eax,(%esp)
c0105f73:	e8 1e f7 ff ff       	call   c0105696 <get_pte>
c0105f78:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0105f7b:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0105f7f:	75 24                	jne    c0105fa5 <check_pgdir+0x4c6>
c0105f81:	c7 44 24 0c f8 b0 10 	movl   $0xc010b0f8,0xc(%esp)
c0105f88:	c0 
c0105f89:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105f90:	c0 
c0105f91:	c7 44 24 04 af 02 00 	movl   $0x2af,0x4(%esp)
c0105f98:	00 
c0105f99:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105fa0:	e8 a0 ac ff ff       	call   c0100c45 <__panic>
    // 验证页表项对应的页面是 p1
    assert(pte2page(*ptep) == p1);
c0105fa5:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105fa8:	8b 00                	mov    (%eax),%eax
c0105faa:	89 04 24             	mov    %eax,(%esp)
c0105fad:	e8 bf ed ff ff       	call   c0104d71 <pte2page>
c0105fb2:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0105fb5:	74 24                	je     c0105fdb <check_pgdir+0x4fc>
c0105fb7:	c7 44 24 0c 6d b0 10 	movl   $0xc010b06d,0xc(%esp)
c0105fbe:	c0 
c0105fbf:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105fc6:	c0 
c0105fc7:	c7 44 24 04 b1 02 00 	movl   $0x2b1,0x4(%esp)
c0105fce:	00 
c0105fcf:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0105fd6:	e8 6a ac ff ff       	call   c0100c45 <__panic>
     // 验证页表项没有设置用户权限
    assert((*ptep & PTE_U) == 0);
c0105fdb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0105fde:	8b 00                	mov    (%eax),%eax
c0105fe0:	83 e0 04             	and    $0x4,%eax
c0105fe3:	85 c0                	test   %eax,%eax
c0105fe5:	74 24                	je     c010600b <check_pgdir+0x52c>
c0105fe7:	c7 44 24 0c bc b1 10 	movl   $0xc010b1bc,0xc(%esp)
c0105fee:	c0 
c0105fef:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0105ff6:	c0 
c0105ff7:	c7 44 24 04 b3 02 00 	movl   $0x2b3,0x4(%esp)
c0105ffe:	00 
c0105fff:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0106006:	e8 3a ac ff ff       	call   c0100c45 <__panic>
    
    //移除虚拟地址 0x0 的映射，
    page_remove(boot_pgdir, 0x0);
c010600b:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0106010:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0106017:	00 
c0106018:	89 04 24             	mov    %eax,(%esp)
c010601b:	e8 70 f8 ff ff       	call   c0105890 <page_remove>
    //验证 p1 的引用计数减少到 1。
    assert(page_ref(p1) == 1);
c0106020:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106023:	89 04 24             	mov    %eax,(%esp)
c0106026:	e8 a0 ed ff ff       	call   c0104dcb <page_ref>
c010602b:	83 f8 01             	cmp    $0x1,%eax
c010602e:	74 24                	je     c0106054 <check_pgdir+0x575>
c0106030:	c7 44 24 0c 83 b0 10 	movl   $0xc010b083,0xc(%esp)
c0106037:	c0 
c0106038:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c010603f:	c0 
c0106040:	c7 44 24 04 b8 02 00 	movl   $0x2b8,0x4(%esp)
c0106047:	00 
c0106048:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c010604f:	e8 f1 ab ff ff       	call   c0100c45 <__panic>
    //验证 p2 的引用计数减少到 0
    assert(page_ref(p2) == 0);
c0106054:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106057:	89 04 24             	mov    %eax,(%esp)
c010605a:	e8 6c ed ff ff       	call   c0104dcb <page_ref>
c010605f:	85 c0                	test   %eax,%eax
c0106061:	74 24                	je     c0106087 <check_pgdir+0x5a8>
c0106063:	c7 44 24 0c aa b1 10 	movl   $0xc010b1aa,0xc(%esp)
c010606a:	c0 
c010606b:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0106072:	c0 
c0106073:	c7 44 24 04 ba 02 00 	movl   $0x2ba,0x4(%esp)
c010607a:	00 
c010607b:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0106082:	e8 be ab ff ff       	call   c0100c45 <__panic>

    //移除虚拟地址 PGSIZE 的映射，
    page_remove(boot_pgdir, PGSIZE);
c0106087:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c010608c:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0106093:	00 
c0106094:	89 04 24             	mov    %eax,(%esp)
c0106097:	e8 f4 f7 ff ff       	call   c0105890 <page_remove>
    //验证 p1 的引用计数减少到 0
    assert(page_ref(p1) == 0);
c010609c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010609f:	89 04 24             	mov    %eax,(%esp)
c01060a2:	e8 24 ed ff ff       	call   c0104dcb <page_ref>
c01060a7:	85 c0                	test   %eax,%eax
c01060a9:	74 24                	je     c01060cf <check_pgdir+0x5f0>
c01060ab:	c7 44 24 0c d1 b1 10 	movl   $0xc010b1d1,0xc(%esp)
c01060b2:	c0 
c01060b3:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c01060ba:	c0 
c01060bb:	c7 44 24 04 bf 02 00 	movl   $0x2bf,0x4(%esp)
c01060c2:	00 
c01060c3:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01060ca:	e8 76 ab ff ff       	call   c0100c45 <__panic>
    //验证 p2 的引用计数减少到 0
    assert(page_ref(p2) == 0);
c01060cf:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01060d2:	89 04 24             	mov    %eax,(%esp)
c01060d5:	e8 f1 ec ff ff       	call   c0104dcb <page_ref>
c01060da:	85 c0                	test   %eax,%eax
c01060dc:	74 24                	je     c0106102 <check_pgdir+0x623>
c01060de:	c7 44 24 0c aa b1 10 	movl   $0xc010b1aa,0xc(%esp)
c01060e5:	c0 
c01060e6:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c01060ed:	c0 
c01060ee:	c7 44 24 04 c1 02 00 	movl   $0x2c1,0x4(%esp)
c01060f5:	00 
c01060f6:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01060fd:	e8 43 ab ff ff       	call   c0100c45 <__panic>
    
    //验证页目录的第一页表的引用计数为 1。
    assert(page_ref(pde2page(boot_pgdir[0])) == 1);
c0106102:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0106107:	8b 00                	mov    (%eax),%eax
c0106109:	89 04 24             	mov    %eax,(%esp)
c010610c:	e8 a0 ec ff ff       	call   c0104db1 <pde2page>
c0106111:	89 04 24             	mov    %eax,(%esp)
c0106114:	e8 b2 ec ff ff       	call   c0104dcb <page_ref>
c0106119:	83 f8 01             	cmp    $0x1,%eax
c010611c:	74 24                	je     c0106142 <check_pgdir+0x663>
c010611e:	c7 44 24 0c e4 b1 10 	movl   $0xc010b1e4,0xc(%esp)
c0106125:	c0 
c0106126:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c010612d:	c0 
c010612e:	c7 44 24 04 c4 02 00 	movl   $0x2c4,0x4(%esp)
c0106135:	00 
c0106136:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c010613d:	e8 03 ab ff ff       	call   c0100c45 <__panic>
    //释放页目录的第一页表
    free_page(pde2page(boot_pgdir[0]));
c0106142:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0106147:	8b 00                	mov    (%eax),%eax
c0106149:	89 04 24             	mov    %eax,(%esp)
c010614c:	e8 60 ec ff ff       	call   c0104db1 <pde2page>
c0106151:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0106158:	00 
c0106159:	89 04 24             	mov    %eax,(%esp)
c010615c:	e8 e7 ee ff ff       	call   c0105048 <free_pages>
    //清空页目录的第一页表
    boot_pgdir[0] = 0;
c0106161:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0106166:	c7 00 00 00 00 00    	movl   $0x0,(%eax)

    cprintf("check_pgdir() succeeded!\n");
c010616c:	c7 04 24 0b b2 10 c0 	movl   $0xc010b20b,(%esp)
c0106173:	e8 00 a2 ff ff       	call   c0100378 <cprintf>
}
c0106178:	90                   	nop
c0106179:	89 ec                	mov    %ebp,%esp
c010617b:	5d                   	pop    %ebp
c010617c:	c3                   	ret    

c010617d <check_boot_pgdir>:

//检查内核页表 boot_pgdir 的正确性
static void
check_boot_pgdir(void) {
c010617d:	55                   	push   %ebp
c010617e:	89 e5                	mov    %esp,%ebp
c0106180:	83 ec 38             	sub    $0x38,%esp
    pte_t *ptep;// 定义一个指向页表项的指针
    int i;
    for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面
c0106183:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c010618a:	e9 ca 00 00 00       	jmp    c0106259 <check_boot_pgdir+0xdc>
        // 获取第 i 个页面的页表项，并确保其不为空
        assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL);
c010618f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106192:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0106195:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106198:	c1 e8 0c             	shr    $0xc,%eax
c010619b:	89 45 e0             	mov    %eax,-0x20(%ebp)
c010619e:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c01061a3:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c01061a6:	72 23                	jb     c01061cb <check_boot_pgdir+0x4e>
c01061a8:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01061ab:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01061af:	c7 44 24 08 3c ae 10 	movl   $0xc010ae3c,0x8(%esp)
c01061b6:	c0 
c01061b7:	c7 44 24 04 d4 02 00 	movl   $0x2d4,0x4(%esp)
c01061be:	00 
c01061bf:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01061c6:	e8 7a aa ff ff       	call   c0100c45 <__panic>
c01061cb:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01061ce:	2d 00 00 00 40       	sub    $0x40000000,%eax
c01061d3:	89 c2                	mov    %eax,%edx
c01061d5:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c01061da:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01061e1:	00 
c01061e2:	89 54 24 04          	mov    %edx,0x4(%esp)
c01061e6:	89 04 24             	mov    %eax,(%esp)
c01061e9:	e8 a8 f4 ff ff       	call   c0105696 <get_pte>
c01061ee:	89 45 dc             	mov    %eax,-0x24(%ebp)
c01061f1:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c01061f5:	75 24                	jne    c010621b <check_boot_pgdir+0x9e>
c01061f7:	c7 44 24 0c 28 b2 10 	movl   $0xc010b228,0xc(%esp)
c01061fe:	c0 
c01061ff:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0106206:	c0 
c0106207:	c7 44 24 04 d4 02 00 	movl   $0x2d4,0x4(%esp)
c010620e:	00 
c010620f:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0106216:	e8 2a aa ff ff       	call   c0100c45 <__panic>
        // 验证页表项的物理地址是否正确
        assert(PTE_ADDR(*ptep) == i);
c010621b:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010621e:	8b 00                	mov    (%eax),%eax
c0106220:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0106225:	89 c2                	mov    %eax,%edx
c0106227:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010622a:	39 c2                	cmp    %eax,%edx
c010622c:	74 24                	je     c0106252 <check_boot_pgdir+0xd5>
c010622e:	c7 44 24 0c 65 b2 10 	movl   $0xc010b265,0xc(%esp)
c0106235:	c0 
c0106236:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c010623d:	c0 
c010623e:	c7 44 24 04 d6 02 00 	movl   $0x2d6,0x4(%esp)
c0106245:	00 
c0106246:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c010624d:	e8 f3 a9 ff ff       	call   c0100c45 <__panic>
    for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面
c0106252:	81 45 f4 00 10 00 00 	addl   $0x1000,-0xc(%ebp)
c0106259:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010625c:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c0106261:	39 c2                	cmp    %eax,%edx
c0106263:	0f 82 26 ff ff ff    	jb     c010618f <check_boot_pgdir+0x12>
    }
    // 验证页目录项的物理地址是否正确
    assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir));
c0106269:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c010626e:	05 ac 0f 00 00       	add    $0xfac,%eax
c0106273:	8b 00                	mov    (%eax),%eax
c0106275:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c010627a:	89 c2                	mov    %eax,%edx
c010627c:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0106281:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0106284:	81 7d f0 ff ff ff bf 	cmpl   $0xbfffffff,-0x10(%ebp)
c010628b:	77 23                	ja     c01062b0 <check_boot_pgdir+0x133>
c010628d:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106290:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0106294:	c7 44 24 08 e0 ae 10 	movl   $0xc010aee0,0x8(%esp)
c010629b:	c0 
c010629c:	c7 44 24 04 d9 02 00 	movl   $0x2d9,0x4(%esp)
c01062a3:	00 
c01062a4:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01062ab:	e8 95 a9 ff ff       	call   c0100c45 <__panic>
c01062b0:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01062b3:	05 00 00 00 40       	add    $0x40000000,%eax
c01062b8:	39 d0                	cmp    %edx,%eax
c01062ba:	74 24                	je     c01062e0 <check_boot_pgdir+0x163>
c01062bc:	c7 44 24 0c 7c b2 10 	movl   $0xc010b27c,0xc(%esp)
c01062c3:	c0 
c01062c4:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c01062cb:	c0 
c01062cc:	c7 44 24 04 d9 02 00 	movl   $0x2d9,0x4(%esp)
c01062d3:	00 
c01062d4:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01062db:	e8 65 a9 ff ff       	call   c0100c45 <__panic>

    assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0
c01062e0:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c01062e5:	8b 00                	mov    (%eax),%eax
c01062e7:	85 c0                	test   %eax,%eax
c01062e9:	74 24                	je     c010630f <check_boot_pgdir+0x192>
c01062eb:	c7 44 24 0c b0 b2 10 	movl   $0xc010b2b0,0xc(%esp)
c01062f2:	c0 
c01062f3:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c01062fa:	c0 
c01062fb:	c7 44 24 04 db 02 00 	movl   $0x2db,0x4(%esp)
c0106302:	00 
c0106303:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c010630a:	e8 36 a9 ff ff       	call   c0100c45 <__panic>

    struct Page *p;// 定义一个指向页面的指针
    p = alloc_page();// 分配一个页面
c010630f:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0106316:	e8 c0 ec ff ff       	call   c0104fdb <alloc_pages>
c010631b:	89 45 ec             	mov    %eax,-0x14(%ebp)
    // 将页面插入到虚拟地址 0x100，并确保操作成功
    assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0);
c010631e:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c0106323:	c7 44 24 0c 02 00 00 	movl   $0x2,0xc(%esp)
c010632a:	00 
c010632b:	c7 44 24 08 00 01 00 	movl   $0x100,0x8(%esp)
c0106332:	00 
c0106333:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0106336:	89 54 24 04          	mov    %edx,0x4(%esp)
c010633a:	89 04 24             	mov    %eax,(%esp)
c010633d:	e8 95 f5 ff ff       	call   c01058d7 <page_insert>
c0106342:	85 c0                	test   %eax,%eax
c0106344:	74 24                	je     c010636a <check_boot_pgdir+0x1ed>
c0106346:	c7 44 24 0c c4 b2 10 	movl   $0xc010b2c4,0xc(%esp)
c010634d:	c0 
c010634e:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0106355:	c0 
c0106356:	c7 44 24 04 e0 02 00 	movl   $0x2e0,0x4(%esp)
c010635d:	00 
c010635e:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0106365:	e8 db a8 ff ff       	call   c0100c45 <__panic>
    assert(page_ref(p) == 1);// 验证页面的引用计数为1
c010636a:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010636d:	89 04 24             	mov    %eax,(%esp)
c0106370:	e8 56 ea ff ff       	call   c0104dcb <page_ref>
c0106375:	83 f8 01             	cmp    $0x1,%eax
c0106378:	74 24                	je     c010639e <check_boot_pgdir+0x221>
c010637a:	c7 44 24 0c f2 b2 10 	movl   $0xc010b2f2,0xc(%esp)
c0106381:	c0 
c0106382:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0106389:	c0 
c010638a:	c7 44 24 04 e1 02 00 	movl   $0x2e1,0x4(%esp)
c0106391:	00 
c0106392:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0106399:	e8 a7 a8 ff ff       	call   c0100c45 <__panic>
    // 将页面插入到虚拟地址 0x100 + PGSIZE，并确保操作成功
    assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0);
c010639e:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c01063a3:	c7 44 24 0c 02 00 00 	movl   $0x2,0xc(%esp)
c01063aa:	00 
c01063ab:	c7 44 24 08 00 11 00 	movl   $0x1100,0x8(%esp)
c01063b2:	00 
c01063b3:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01063b6:	89 54 24 04          	mov    %edx,0x4(%esp)
c01063ba:	89 04 24             	mov    %eax,(%esp)
c01063bd:	e8 15 f5 ff ff       	call   c01058d7 <page_insert>
c01063c2:	85 c0                	test   %eax,%eax
c01063c4:	74 24                	je     c01063ea <check_boot_pgdir+0x26d>
c01063c6:	c7 44 24 0c 04 b3 10 	movl   $0xc010b304,0xc(%esp)
c01063cd:	c0 
c01063ce:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c01063d5:	c0 
c01063d6:	c7 44 24 04 e3 02 00 	movl   $0x2e3,0x4(%esp)
c01063dd:	00 
c01063de:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01063e5:	e8 5b a8 ff ff       	call   c0100c45 <__panic>
    assert(page_ref(p) == 2);// 验证页面的引用计数为2
c01063ea:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01063ed:	89 04 24             	mov    %eax,(%esp)
c01063f0:	e8 d6 e9 ff ff       	call   c0104dcb <page_ref>
c01063f5:	83 f8 02             	cmp    $0x2,%eax
c01063f8:	74 24                	je     c010641e <check_boot_pgdir+0x2a1>
c01063fa:	c7 44 24 0c 3b b3 10 	movl   $0xc010b33b,0xc(%esp)
c0106401:	c0 
c0106402:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c0106409:	c0 
c010640a:	c7 44 24 04 e4 02 00 	movl   $0x2e4,0x4(%esp)
c0106411:	00 
c0106412:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c0106419:	e8 27 a8 ff ff       	call   c0100c45 <__panic>

    const char *str = "ucore: Hello world!!";// 定义一个字符串
c010641e:	c7 45 e8 4c b3 10 c0 	movl   $0xc010b34c,-0x18(%ebp)
    strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100
c0106425:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106428:	89 44 24 04          	mov    %eax,0x4(%esp)
c010642c:	c7 04 24 00 01 00 00 	movl   $0x100,(%esp)
c0106433:	e8 dc 37 00 00       	call   c0109c14 <strcpy>
    // 验证两个映射地址的数据是否一致
    assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0);
c0106438:	c7 44 24 04 00 11 00 	movl   $0x1100,0x4(%esp)
c010643f:	00 
c0106440:	c7 04 24 00 01 00 00 	movl   $0x100,(%esp)
c0106447:	e8 40 38 00 00       	call   c0109c8c <strcmp>
c010644c:	85 c0                	test   %eax,%eax
c010644e:	74 24                	je     c0106474 <check_boot_pgdir+0x2f7>
c0106450:	c7 44 24 0c 64 b3 10 	movl   $0xc010b364,0xc(%esp)
c0106457:	c0 
c0106458:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c010645f:	c0 
c0106460:	c7 44 24 04 e9 02 00 	movl   $0x2e9,0x4(%esp)
c0106467:	00 
c0106468:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c010646f:	e8 d1 a7 ff ff       	call   c0100c45 <__panic>
    // 在页面的 0x100 偏移处设置字符串结束符
    *(char *)(page2kva(p) + 0x100) = '\0';
c0106474:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106477:	89 04 24             	mov    %eax,(%esp)
c010647a:	e8 9c e8 ff ff       	call   c0104d1b <page2kva>
c010647f:	05 00 01 00 00       	add    $0x100,%eax
c0106484:	c6 00 00             	movb   $0x0,(%eax)
    assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0
c0106487:	c7 04 24 00 01 00 00 	movl   $0x100,(%esp)
c010648e:	e8 27 37 00 00       	call   c0109bba <strlen>
c0106493:	85 c0                	test   %eax,%eax
c0106495:	74 24                	je     c01064bb <check_boot_pgdir+0x33e>
c0106497:	c7 44 24 0c 9c b3 10 	movl   $0xc010b39c,0xc(%esp)
c010649e:	c0 
c010649f:	c7 44 24 08 29 af 10 	movl   $0xc010af29,0x8(%esp)
c01064a6:	c0 
c01064a7:	c7 44 24 04 ec 02 00 	movl   $0x2ec,0x4(%esp)
c01064ae:	00 
c01064af:	c7 04 24 04 af 10 c0 	movl   $0xc010af04,(%esp)
c01064b6:	e8 8a a7 ff ff       	call   c0100c45 <__panic>

    free_page(p);// 释放页面 p
c01064bb:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01064c2:	00 
c01064c3:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01064c6:	89 04 24             	mov    %eax,(%esp)
c01064c9:	e8 7a eb ff ff       	call   c0105048 <free_pages>
    free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面
c01064ce:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c01064d3:	8b 00                	mov    (%eax),%eax
c01064d5:	89 04 24             	mov    %eax,(%esp)
c01064d8:	e8 d4 e8 ff ff       	call   c0104db1 <pde2page>
c01064dd:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01064e4:	00 
c01064e5:	89 04 24             	mov    %eax,(%esp)
c01064e8:	e8 5b eb ff ff       	call   c0105048 <free_pages>
    boot_pgdir[0] = 0;// 将页目录的第一个项设为0
c01064ed:	a1 00 8a 12 c0       	mov    0xc0128a00,%eax
c01064f2:	c7 00 00 00 00 00    	movl   $0x0,(%eax)

    cprintf("check_boot_pgdir() succeeded!\n");// 输出成功信息
c01064f8:	c7 04 24 c0 b3 10 c0 	movl   $0xc010b3c0,(%esp)
c01064ff:	e8 74 9e ff ff       	call   c0100378 <cprintf>
}
c0106504:	90                   	nop
c0106505:	89 ec                	mov    %ebp,%esp
c0106507:	5d                   	pop    %ebp
c0106508:	c3                   	ret    

c0106509 <perm2str>:

//perm2str - use string 'u,r,w,-' to present the permission
static const char *
perm2str(int perm) {
c0106509:	55                   	push   %ebp
c010650a:	89 e5                	mov    %esp,%ebp
    //定义一个静态字符数组 str，长度为4
    static char str[4];
    //如果 perm 与 PTE_U 按位与的结果不为0，则 str[0] 设置为 'u'，否则设置为 '-'
    str[0] = (perm & PTE_U) ? 'u' : '-';
c010650c:	8b 45 08             	mov    0x8(%ebp),%eax
c010650f:	83 e0 04             	and    $0x4,%eax
c0106512:	85 c0                	test   %eax,%eax
c0106514:	74 04                	je     c010651a <perm2str+0x11>
c0106516:	b0 75                	mov    $0x75,%al
c0106518:	eb 02                	jmp    c010651c <perm2str+0x13>
c010651a:	b0 2d                	mov    $0x2d,%al
c010651c:	a2 88 c0 12 c0       	mov    %al,0xc012c088
    //str[1] 始终设置为 'r'
    str[1] = 'r';
c0106521:	c6 05 89 c0 12 c0 72 	movb   $0x72,0xc012c089
    //如果 perm 与 PTE_W 按位与的结果不为0，则 str[2] 设置为 'w'，否则设置为 '-'
    str[2] = (perm & PTE_W) ? 'w' : '-';
c0106528:	8b 45 08             	mov    0x8(%ebp),%eax
c010652b:	83 e0 02             	and    $0x2,%eax
c010652e:	85 c0                	test   %eax,%eax
c0106530:	74 04                	je     c0106536 <perm2str+0x2d>
c0106532:	b0 77                	mov    $0x77,%al
c0106534:	eb 02                	jmp    c0106538 <perm2str+0x2f>
c0106536:	b0 2d                	mov    $0x2d,%al
c0106538:	a2 8a c0 12 c0       	mov    %al,0xc012c08a
    //str[3] 设置为字符串结束符 \0
    str[3] = '\0';
c010653d:	c6 05 8b c0 12 c0 00 	movb   $0x0,0xc012c08b
    return str;
c0106544:	b8 88 c0 12 c0       	mov    $0xc012c088,%eax
}
c0106549:	5d                   	pop    %ebp
c010654a:	c3                   	ret    

c010654b <get_pgtable_items>:
//  left_store:  the pointer of the high side of table's next range
//  right_store: the pointer of the low side of table's next range
// return value: 0 - not a invalid item range, perm - a valid item range with perm permission 
//从页表中获取指定范围内的有效项，并根据权限进行处理。
static int
get_pgtable_items(size_t left, size_t right, size_t start, uintptr_t *table, size_t *left_store, size_t *right_store) {
c010654b:	55                   	push   %ebp
c010654c:	89 e5                	mov    %esp,%ebp
c010654e:	83 ec 10             	sub    $0x10,%esp
    if (start >= right) {// 检查起始索引是否超出右边界
c0106551:	8b 45 10             	mov    0x10(%ebp),%eax
c0106554:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0106557:	72 0d                	jb     c0106566 <get_pgtable_items+0x1b>
        return 0;// 如果超出右边界，返回0
c0106559:	b8 00 00 00 00       	mov    $0x0,%eax
c010655e:	e9 98 00 00 00       	jmp    c01065fb <get_pgtable_items+0xb0>
    }
    while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项（PTE_P位为1的项）
        start ++;// 索引递增
c0106563:	ff 45 10             	incl   0x10(%ebp)
    while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项（PTE_P位为1的项）
c0106566:	8b 45 10             	mov    0x10(%ebp),%eax
c0106569:	3b 45 0c             	cmp    0xc(%ebp),%eax
c010656c:	73 18                	jae    c0106586 <get_pgtable_items+0x3b>
c010656e:	8b 45 10             	mov    0x10(%ebp),%eax
c0106571:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c0106578:	8b 45 14             	mov    0x14(%ebp),%eax
c010657b:	01 d0                	add    %edx,%eax
c010657d:	8b 00                	mov    (%eax),%eax
c010657f:	83 e0 01             	and    $0x1,%eax
c0106582:	85 c0                	test   %eax,%eax
c0106584:	74 dd                	je     c0106563 <get_pgtable_items+0x18>
    }
    if (start < right) {// 检查是否找到有效项
c0106586:	8b 45 10             	mov    0x10(%ebp),%eax
c0106589:	3b 45 0c             	cmp    0xc(%ebp),%eax
c010658c:	73 68                	jae    c01065f6 <get_pgtable_items+0xab>
        if (left_store != NULL) {// 如果left_store不为NULL
c010658e:	83 7d 18 00          	cmpl   $0x0,0x18(%ebp)
c0106592:	74 08                	je     c010659c <get_pgtable_items+0x51>
            *left_store = start;// 记录左边界索引
c0106594:	8b 45 18             	mov    0x18(%ebp),%eax
c0106597:	8b 55 10             	mov    0x10(%ebp),%edx
c010659a:	89 10                	mov    %edx,(%eax)
        }
        int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引
c010659c:	8b 45 10             	mov    0x10(%ebp),%eax
c010659f:	8d 50 01             	lea    0x1(%eax),%edx
c01065a2:	89 55 10             	mov    %edx,0x10(%ebp)
c01065a5:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c01065ac:	8b 45 14             	mov    0x14(%ebp),%eax
c01065af:	01 d0                	add    %edx,%eax
c01065b1:	8b 00                	mov    (%eax),%eax
c01065b3:	83 e0 07             	and    $0x7,%eax
c01065b6:	89 45 fc             	mov    %eax,-0x4(%ebp)
        while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项
c01065b9:	eb 03                	jmp    c01065be <get_pgtable_items+0x73>
            start ++;// 索引递增
c01065bb:	ff 45 10             	incl   0x10(%ebp)
        while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项
c01065be:	8b 45 10             	mov    0x10(%ebp),%eax
c01065c1:	3b 45 0c             	cmp    0xc(%ebp),%eax
c01065c4:	73 1d                	jae    c01065e3 <get_pgtable_items+0x98>
c01065c6:	8b 45 10             	mov    0x10(%ebp),%eax
c01065c9:	8d 14 85 00 00 00 00 	lea    0x0(,%eax,4),%edx
c01065d0:	8b 45 14             	mov    0x14(%ebp),%eax
c01065d3:	01 d0                	add    %edx,%eax
c01065d5:	8b 00                	mov    (%eax),%eax
c01065d7:	83 e0 07             	and    $0x7,%eax
c01065da:	89 c2                	mov    %eax,%edx
c01065dc:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01065df:	39 c2                	cmp    %eax,%edx
c01065e1:	74 d8                	je     c01065bb <get_pgtable_items+0x70>
        }
        if (right_store != NULL) {// 如果right_store不为NULL
c01065e3:	83 7d 1c 00          	cmpl   $0x0,0x1c(%ebp)
c01065e7:	74 08                	je     c01065f1 <get_pgtable_items+0xa6>
            *right_store = start;// 记录右边界索引
c01065e9:	8b 45 1c             	mov    0x1c(%ebp),%eax
c01065ec:	8b 55 10             	mov    0x10(%ebp),%edx
c01065ef:	89 10                	mov    %edx,(%eax)
        }
        return perm;// 返回用户权限位
c01065f1:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01065f4:	eb 05                	jmp    c01065fb <get_pgtable_items+0xb0>
    }
    return 0;// 如果未找到有效项，返回0
c01065f6:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01065fb:	89 ec                	mov    %ebp,%esp
c01065fd:	5d                   	pop    %ebp
c01065fe:	c3                   	ret    

c01065ff <print_pgdir>:

//print_pgdir - print the PDT&PT
void
print_pgdir(void) {
c01065ff:	55                   	push   %ebp
c0106600:	89 e5                	mov    %esp,%ebp
c0106602:	57                   	push   %edi
c0106603:	56                   	push   %esi
c0106604:	53                   	push   %ebx
c0106605:	83 ec 4c             	sub    $0x4c,%esp
    cprintf("-------------------- BEGIN --------------------\n");
c0106608:	c7 04 24 e0 b3 10 c0 	movl   $0xc010b3e0,(%esp)
c010660f:	e8 64 9d ff ff       	call   c0100378 <cprintf>
    // 定义变量 left, right 和 perm
    size_t left, right = 0, perm;
c0106614:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
    // 遍历页目录项
    while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) {
c010661b:	e9 f2 00 00 00       	jmp    c0106712 <print_pgdir+0x113>
        // 打印页目录项的信息
        cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left,
c0106620:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106623:	89 04 24             	mov    %eax,(%esp)
c0106626:	e8 de fe ff ff       	call   c0106509 <perm2str>
                left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm));
c010662b:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010662e:	8b 4d e0             	mov    -0x20(%ebp),%ecx
c0106631:	29 ca                	sub    %ecx,%edx
        cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left,
c0106633:	89 d6                	mov    %edx,%esi
c0106635:	c1 e6 16             	shl    $0x16,%esi
c0106638:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010663b:	89 d3                	mov    %edx,%ebx
c010663d:	c1 e3 16             	shl    $0x16,%ebx
c0106640:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0106643:	89 d1                	mov    %edx,%ecx
c0106645:	c1 e1 16             	shl    $0x16,%ecx
c0106648:	8b 55 dc             	mov    -0x24(%ebp),%edx
c010664b:	8b 7d e0             	mov    -0x20(%ebp),%edi
c010664e:	29 fa                	sub    %edi,%edx
c0106650:	89 44 24 14          	mov    %eax,0x14(%esp)
c0106654:	89 74 24 10          	mov    %esi,0x10(%esp)
c0106658:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
c010665c:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c0106660:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106664:	c7 04 24 11 b4 10 c0 	movl   $0xc010b411,(%esp)
c010666b:	e8 08 9d ff ff       	call   c0100378 <cprintf>
        // 计算页表项的起始和结束索引
        size_t l, r = left * NPTEENTRY;
c0106670:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0106673:	c1 e0 0a             	shl    $0xa,%eax
c0106676:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        // 遍历页表项
        while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) {
c0106679:	eb 50                	jmp    c01066cb <print_pgdir+0xcc>
            // 打印页表项的信息
            cprintf("  |-- PTE(%05x) %08x-%08x %08x %s\n", r - l,
c010667b:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010667e:	89 04 24             	mov    %eax,(%esp)
c0106681:	e8 83 fe ff ff       	call   c0106509 <perm2str>
                    l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm));
c0106686:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0106689:	8b 4d d8             	mov    -0x28(%ebp),%ecx
c010668c:	29 ca                	sub    %ecx,%edx
            cprintf("  |-- PTE(%05x) %08x-%08x %08x %s\n", r - l,
c010668e:	89 d6                	mov    %edx,%esi
c0106690:	c1 e6 0c             	shl    $0xc,%esi
c0106693:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0106696:	89 d3                	mov    %edx,%ebx
c0106698:	c1 e3 0c             	shl    $0xc,%ebx
c010669b:	8b 55 d8             	mov    -0x28(%ebp),%edx
c010669e:	89 d1                	mov    %edx,%ecx
c01066a0:	c1 e1 0c             	shl    $0xc,%ecx
c01066a3:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c01066a6:	8b 7d d8             	mov    -0x28(%ebp),%edi
c01066a9:	29 fa                	sub    %edi,%edx
c01066ab:	89 44 24 14          	mov    %eax,0x14(%esp)
c01066af:	89 74 24 10          	mov    %esi,0x10(%esp)
c01066b3:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
c01066b7:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c01066bb:	89 54 24 04          	mov    %edx,0x4(%esp)
c01066bf:	c7 04 24 30 b4 10 c0 	movl   $0xc010b430,(%esp)
c01066c6:	e8 ad 9c ff ff       	call   c0100378 <cprintf>
        while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) {
c01066cb:	be 00 00 c0 fa       	mov    $0xfac00000,%esi
c01066d0:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01066d3:	8b 55 dc             	mov    -0x24(%ebp),%edx
c01066d6:	89 d3                	mov    %edx,%ebx
c01066d8:	c1 e3 0a             	shl    $0xa,%ebx
c01066db:	8b 55 e0             	mov    -0x20(%ebp),%edx
c01066de:	89 d1                	mov    %edx,%ecx
c01066e0:	c1 e1 0a             	shl    $0xa,%ecx
c01066e3:	8d 55 d4             	lea    -0x2c(%ebp),%edx
c01066e6:	89 54 24 14          	mov    %edx,0x14(%esp)
c01066ea:	8d 55 d8             	lea    -0x28(%ebp),%edx
c01066ed:	89 54 24 10          	mov    %edx,0x10(%esp)
c01066f1:	89 74 24 0c          	mov    %esi,0xc(%esp)
c01066f5:	89 44 24 08          	mov    %eax,0x8(%esp)
c01066f9:	89 5c 24 04          	mov    %ebx,0x4(%esp)
c01066fd:	89 0c 24             	mov    %ecx,(%esp)
c0106700:	e8 46 fe ff ff       	call   c010654b <get_pgtable_items>
c0106705:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0106708:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c010670c:	0f 85 69 ff ff ff    	jne    c010667b <print_pgdir+0x7c>
    while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) {
c0106712:	b9 00 b0 fe fa       	mov    $0xfafeb000,%ecx
c0106717:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010671a:	8d 55 dc             	lea    -0x24(%ebp),%edx
c010671d:	89 54 24 14          	mov    %edx,0x14(%esp)
c0106721:	8d 55 e0             	lea    -0x20(%ebp),%edx
c0106724:	89 54 24 10          	mov    %edx,0x10(%esp)
c0106728:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c010672c:	89 44 24 08          	mov    %eax,0x8(%esp)
c0106730:	c7 44 24 04 00 04 00 	movl   $0x400,0x4(%esp)
c0106737:	00 
c0106738:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c010673f:	e8 07 fe ff ff       	call   c010654b <get_pgtable_items>
c0106744:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0106747:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c010674b:	0f 85 cf fe ff ff    	jne    c0106620 <print_pgdir+0x21>
        }
    }
    cprintf("--------------------- END ---------------------\n");
c0106751:	c7 04 24 54 b4 10 c0 	movl   $0xc010b454,(%esp)
c0106758:	e8 1b 9c ff ff       	call   c0100378 <cprintf>
}
c010675d:	90                   	nop
c010675e:	83 c4 4c             	add    $0x4c,%esp
c0106761:	5b                   	pop    %ebx
c0106762:	5e                   	pop    %esi
c0106763:	5f                   	pop    %edi
c0106764:	5d                   	pop    %ebp
c0106765:	c3                   	ret    

c0106766 <pa2page>:
pa2page(uintptr_t pa) {
c0106766:	55                   	push   %ebp
c0106767:	89 e5                	mov    %esp,%ebp
c0106769:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c010676c:	8b 45 08             	mov    0x8(%ebp),%eax
c010676f:	c1 e8 0c             	shr    $0xc,%eax
c0106772:	89 c2                	mov    %eax,%edx
c0106774:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c0106779:	39 c2                	cmp    %eax,%edx
c010677b:	72 1c                	jb     c0106799 <pa2page+0x33>
        panic("pa2page called with invalid pa");
c010677d:	c7 44 24 08 88 b4 10 	movl   $0xc010b488,0x8(%esp)
c0106784:	c0 
c0106785:	c7 44 24 04 5f 00 00 	movl   $0x5f,0x4(%esp)
c010678c:	00 
c010678d:	c7 04 24 a7 b4 10 c0 	movl   $0xc010b4a7,(%esp)
c0106794:	e8 ac a4 ff ff       	call   c0100c45 <__panic>
    return &pages[PPN(pa)];
c0106799:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c010679f:	8b 45 08             	mov    0x8(%ebp),%eax
c01067a2:	c1 e8 0c             	shr    $0xc,%eax
c01067a5:	c1 e0 05             	shl    $0x5,%eax
c01067a8:	01 d0                	add    %edx,%eax
}
c01067aa:	89 ec                	mov    %ebp,%esp
c01067ac:	5d                   	pop    %ebp
c01067ad:	c3                   	ret    

c01067ae <pte2page>:
pte2page(pte_t pte) {
c01067ae:	55                   	push   %ebp
c01067af:	89 e5                	mov    %esp,%ebp
c01067b1:	83 ec 18             	sub    $0x18,%esp
    if (!(pte & PTE_P)) {
c01067b4:	8b 45 08             	mov    0x8(%ebp),%eax
c01067b7:	83 e0 01             	and    $0x1,%eax
c01067ba:	85 c0                	test   %eax,%eax
c01067bc:	75 1c                	jne    c01067da <pte2page+0x2c>
        panic("pte2page called with invalid pte");
c01067be:	c7 44 24 08 b8 b4 10 	movl   $0xc010b4b8,0x8(%esp)
c01067c5:	c0 
c01067c6:	c7 44 24 04 71 00 00 	movl   $0x71,0x4(%esp)
c01067cd:	00 
c01067ce:	c7 04 24 a7 b4 10 c0 	movl   $0xc010b4a7,(%esp)
c01067d5:	e8 6b a4 ff ff       	call   c0100c45 <__panic>
    return pa2page(PTE_ADDR(pte));
c01067da:	8b 45 08             	mov    0x8(%ebp),%eax
c01067dd:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c01067e2:	89 04 24             	mov    %eax,(%esp)
c01067e5:	e8 7c ff ff ff       	call   c0106766 <pa2page>
}
c01067ea:	89 ec                	mov    %ebp,%esp
c01067ec:	5d                   	pop    %ebp
c01067ed:	c3                   	ret    

c01067ee <swap_init>:

static void check_swap(void);

int
swap_init(void)
{
c01067ee:	55                   	push   %ebp
c01067ef:	89 e5                	mov    %esp,%ebp
c01067f1:	83 ec 28             	sub    $0x28,%esp
     // 初始化交换文件系统
     swapfs_init();
c01067f4:	e8 a7 1e 00 00       	call   c01086a0 <swapfs_init>

     // 检查最大交换偏移量是否在合法范围内
     if (!(1024 <= max_swap_offset && max_swap_offset < MAX_SWAP_OFFSET_LIMIT))
c01067f9:	a1 a0 c0 12 c0       	mov    0xc012c0a0,%eax
c01067fe:	3d ff 03 00 00       	cmp    $0x3ff,%eax
c0106803:	76 0c                	jbe    c0106811 <swap_init+0x23>
c0106805:	a1 a0 c0 12 c0       	mov    0xc012c0a0,%eax
c010680a:	3d ff ff ff 00       	cmp    $0xffffff,%eax
c010680f:	76 25                	jbe    c0106836 <swap_init+0x48>
     {    
           // 如果最大交换偏移量不合法，输出错误信息并panic
          panic("bad max_swap_offset %08x.\n", max_swap_offset);
c0106811:	a1 a0 c0 12 c0       	mov    0xc012c0a0,%eax
c0106816:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010681a:	c7 44 24 08 d9 b4 10 	movl   $0xc010b4d9,0x8(%esp)
c0106821:	c0 
c0106822:	c7 44 24 04 28 00 00 	movl   $0x28,0x4(%esp)
c0106829:	00 
c010682a:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106831:	e8 0f a4 ff ff       	call   c0100c45 <__panic>
     }
     
     // 选择并设置交换管理器为FIFO（先进先出）策略
     sm = &swap_manager_fifo;
c0106836:	c7 05 60 c1 12 c0 60 	movl   $0xc0128a60,0xc012c160
c010683d:	8a 12 c0 

     // 调用选定交换管理器的初始化函数
     int r = sm->init();
c0106840:	a1 60 c1 12 c0       	mov    0xc012c160,%eax
c0106845:	8b 40 04             	mov    0x4(%eax),%eax
c0106848:	ff d0                	call   *%eax
c010684a:	89 45 f4             	mov    %eax,-0xc(%ebp)

     // 如果交换管理器初始化成功
     if (r == 0)
c010684d:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0106851:	75 26                	jne    c0106879 <swap_init+0x8b>
     {
          // 标记交换空间初始化为成功
          swap_init_ok = 1;
c0106853:	c7 05 a4 c0 12 c0 01 	movl   $0x1,0xc012c0a4
c010685a:	00 00 00 

          cprintf("SWAP: manager = %s\n", sm->name);
c010685d:	a1 60 c1 12 c0       	mov    0xc012c160,%eax
c0106862:	8b 00                	mov    (%eax),%eax
c0106864:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106868:	c7 04 24 03 b5 10 c0 	movl   $0xc010b503,(%esp)
c010686f:	e8 04 9b ff ff       	call   c0100378 <cprintf>
          // 检查交换空间状态
          check_swap();
c0106874:	e8 b0 04 00 00       	call   c0106d29 <check_swap>
     }
     // 返回初始化结果
     return r;
c0106879:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010687c:	89 ec                	mov    %ebp,%esp
c010687e:	5d                   	pop    %ebp
c010687f:	c3                   	ret    

c0106880 <swap_init_mm>:

int
swap_init_mm(struct mm_struct *mm)
{
c0106880:	55                   	push   %ebp
c0106881:	89 e5                	mov    %esp,%ebp
c0106883:	83 ec 18             	sub    $0x18,%esp
     //调用 sm 结构体中的 init_mm 函数，并将 mm 作为参数传递
     return sm->init_mm(mm);
c0106886:	a1 60 c1 12 c0       	mov    0xc012c160,%eax
c010688b:	8b 40 08             	mov    0x8(%eax),%eax
c010688e:	8b 55 08             	mov    0x8(%ebp),%edx
c0106891:	89 14 24             	mov    %edx,(%esp)
c0106894:	ff d0                	call   *%eax
}
c0106896:	89 ec                	mov    %ebp,%esp
c0106898:	5d                   	pop    %ebp
c0106899:	c3                   	ret    

c010689a <swap_tick_event>:
 *
 * 返回值: sm->tick_event(mm)的返回值
 */
int
swap_tick_event(struct mm_struct *mm)
{
c010689a:	55                   	push   %ebp
c010689b:	89 e5                	mov    %esp,%ebp
c010689d:	83 ec 18             	sub    $0x18,%esp
     return sm->tick_event(mm);
c01068a0:	a1 60 c1 12 c0       	mov    0xc012c160,%eax
c01068a5:	8b 40 0c             	mov    0xc(%eax),%eax
c01068a8:	8b 55 08             	mov    0x8(%ebp),%edx
c01068ab:	89 14 24             	mov    %edx,(%esp)
c01068ae:	ff d0                	call   *%eax
}
c01068b0:	89 ec                	mov    %ebp,%esp
c01068b2:	5d                   	pop    %ebp
c01068b3:	c3                   	ret    

c01068b4 <swap_map_swappable>:
 * 此函数的作用是作为交换操作的接口，根据swap_in参数决定是将页面交换入还是交换出
 * 它实际上调用了结构体sm中定义的map_swappable函数，因此具体的操作逻辑依赖于该函数的实现
 */
int
swap_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in)
{
c01068b4:	55                   	push   %ebp
c01068b5:	89 e5                	mov    %esp,%ebp
c01068b7:	83 ec 18             	sub    $0x18,%esp
     return sm->map_swappable(mm, addr, page, swap_in);
c01068ba:	a1 60 c1 12 c0       	mov    0xc012c160,%eax
c01068bf:	8b 40 10             	mov    0x10(%eax),%eax
c01068c2:	8b 55 14             	mov    0x14(%ebp),%edx
c01068c5:	89 54 24 0c          	mov    %edx,0xc(%esp)
c01068c9:	8b 55 10             	mov    0x10(%ebp),%edx
c01068cc:	89 54 24 08          	mov    %edx,0x8(%esp)
c01068d0:	8b 55 0c             	mov    0xc(%ebp),%edx
c01068d3:	89 54 24 04          	mov    %edx,0x4(%esp)
c01068d7:	8b 55 08             	mov    0x8(%ebp),%edx
c01068da:	89 14 24             	mov    %edx,(%esp)
c01068dd:	ff d0                	call   *%eax
}
c01068df:	89 ec                	mov    %ebp,%esp
c01068e1:	5d                   	pop    %ebp
c01068e2:	c3                   	ret    

c01068e3 <swap_set_unswappable>:
 * 此函数通过调用sm->set_unswappable方法来实现，其主要目的是防止指定的内存区域被交换到磁盘，
 * 通常用于那些需要常驻内存不能被交换出的特殊页面。成功时返回0，失败时返回非零值。
 */
int
swap_set_unswappable(struct mm_struct *mm, uintptr_t addr)
{
c01068e3:	55                   	push   %ebp
c01068e4:	89 e5                	mov    %esp,%ebp
c01068e6:	83 ec 18             	sub    $0x18,%esp
     return sm->set_unswappable(mm, addr);
c01068e9:	a1 60 c1 12 c0       	mov    0xc012c160,%eax
c01068ee:	8b 40 14             	mov    0x14(%eax),%eax
c01068f1:	8b 55 0c             	mov    0xc(%ebp),%edx
c01068f4:	89 54 24 04          	mov    %edx,0x4(%esp)
c01068f8:	8b 55 08             	mov    0x8(%ebp),%edx
c01068fb:	89 14 24             	mov    %edx,(%esp)
c01068fe:	ff d0                	call   *%eax
}
c0106900:	89 ec                	mov    %ebp,%esp
c0106902:	5d                   	pop    %ebp
c0106903:	c3                   	ret    

c0106904 <swap_out>:
 * 此函数通过选择 victim 页面并将其内容写入到交换空间中，来实现内存中页面的交换出操作。
 * 它主要用于内存压力较大时，释放内存空间，确保系统稳定运行。
 */
int
swap_out(struct mm_struct *mm, int n, int in_tick)
{
c0106904:	55                   	push   %ebp
c0106905:	89 e5                	mov    %esp,%ebp
c0106907:	83 ec 38             	sub    $0x38,%esp
     int i;
     for (i = 0; i != n; ++ i)// 循环 n 次，每次处理一个页面
c010690a:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0106911:	e9 53 01 00 00       	jmp    c0106a69 <swap_out+0x165>
          uintptr_t v; // 用于存储页面的虚拟地址
          //struct Page **ptr_page=NULL;
          struct Page *page;  // 用于存储选中的页面
          // cprintf("i %d, SWAP: call swap_out_victim\n",i);
          // 调用 swap_out_victim 函数选择一个 victim 页面
          int r = sm->swap_out_victim(mm, &page, in_tick);
c0106916:	a1 60 c1 12 c0       	mov    0xc012c160,%eax
c010691b:	8b 40 18             	mov    0x18(%eax),%eax
c010691e:	8b 55 10             	mov    0x10(%ebp),%edx
c0106921:	89 54 24 08          	mov    %edx,0x8(%esp)
c0106925:	8d 55 e4             	lea    -0x1c(%ebp),%edx
c0106928:	89 54 24 04          	mov    %edx,0x4(%esp)
c010692c:	8b 55 08             	mov    0x8(%ebp),%edx
c010692f:	89 14 24             	mov    %edx,(%esp)
c0106932:	ff d0                	call   *%eax
c0106934:	89 45 f0             	mov    %eax,-0x10(%ebp)
          if (r != 0) {// 如果选择失败
c0106937:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c010693b:	74 18                	je     c0106955 <swap_out+0x51>
                    cprintf("i %d, swap_out: call swap_out_victim failed\n",i);// 输出错误信息
c010693d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106940:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106944:	c7 04 24 18 b5 10 c0 	movl   $0xc010b518,(%esp)
c010694b:	e8 28 9a ff ff       	call   c0100378 <cprintf>
c0106950:	e9 20 01 00 00       	jmp    c0106a75 <swap_out+0x171>
          }          
          //assert(!PageReserved(page));

          //cprintf("SWAP: choose victim page 0x%08x\n", page);
          
          v=page->pra_vaddr;  // 获取页面的虚拟地址
c0106955:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106958:	8b 40 1c             	mov    0x1c(%eax),%eax
c010695b:	89 45 ec             	mov    %eax,-0x14(%ebp)
          pte_t *ptep = get_pte(mm->pgdir, v, 0); // 获取页面表项指针
c010695e:	8b 45 08             	mov    0x8(%ebp),%eax
c0106961:	8b 40 0c             	mov    0xc(%eax),%eax
c0106964:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c010696b:	00 
c010696c:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010696f:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106973:	89 04 24             	mov    %eax,(%esp)
c0106976:	e8 1b ed ff ff       	call   c0105696 <get_pte>
c010697b:	89 45 e8             	mov    %eax,-0x18(%ebp)
          assert((*ptep & PTE_P) != 0); // 断言页面在物理内存中存在
c010697e:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106981:	8b 00                	mov    (%eax),%eax
c0106983:	83 e0 01             	and    $0x1,%eax
c0106986:	85 c0                	test   %eax,%eax
c0106988:	75 24                	jne    c01069ae <swap_out+0xaa>
c010698a:	c7 44 24 0c 45 b5 10 	movl   $0xc010b545,0xc(%esp)
c0106991:	c0 
c0106992:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106999:	c0 
c010699a:	c7 44 24 04 9b 00 00 	movl   $0x9b,0x4(%esp)
c01069a1:	00 
c01069a2:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c01069a9:	e8 97 a2 ff ff       	call   c0100c45 <__panic>

          if (swapfs_write( (page->pra_vaddr/PGSIZE+1)<<8, page) != 0) {// 将页面内容写入交换文件
c01069ae:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01069b1:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c01069b4:	8b 52 1c             	mov    0x1c(%edx),%edx
c01069b7:	c1 ea 0c             	shr    $0xc,%edx
c01069ba:	42                   	inc    %edx
c01069bb:	c1 e2 08             	shl    $0x8,%edx
c01069be:	89 44 24 04          	mov    %eax,0x4(%esp)
c01069c2:	89 14 24             	mov    %edx,(%esp)
c01069c5:	e8 95 1d 00 00       	call   c010875f <swapfs_write>
c01069ca:	85 c0                	test   %eax,%eax
c01069cc:	74 34                	je     c0106a02 <swap_out+0xfe>
                    cprintf("SWAP: failed to save\n");// 如果写入失败，输出错误信息
c01069ce:	c7 04 24 6f b5 10 c0 	movl   $0xc010b56f,(%esp)
c01069d5:	e8 9e 99 ff ff       	call   c0100378 <cprintf>
                    sm->map_swappable(mm, v, page, 0);// 标记页面为不可交换
c01069da:	a1 60 c1 12 c0       	mov    0xc012c160,%eax
c01069df:	8b 40 10             	mov    0x10(%eax),%eax
c01069e2:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c01069e5:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
c01069ec:	00 
c01069ed:	89 54 24 08          	mov    %edx,0x8(%esp)
c01069f1:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01069f4:	89 54 24 04          	mov    %edx,0x4(%esp)
c01069f8:	8b 55 08             	mov    0x8(%ebp),%edx
c01069fb:	89 14 24             	mov    %edx,(%esp)
c01069fe:	ff d0                	call   *%eax
c0106a00:	eb 64                	jmp    c0106a66 <swap_out+0x162>
                    continue;
          }
          else {
                    cprintf("swap_out: i %d, store page in vaddr 0x%x to disk swap entry %d\n", i, v, page->pra_vaddr/PGSIZE+1);
c0106a02:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106a05:	8b 40 1c             	mov    0x1c(%eax),%eax
c0106a08:	c1 e8 0c             	shr    $0xc,%eax
c0106a0b:	40                   	inc    %eax
c0106a0c:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0106a10:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106a13:	89 44 24 08          	mov    %eax,0x8(%esp)
c0106a17:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106a1a:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106a1e:	c7 04 24 88 b5 10 c0 	movl   $0xc010b588,(%esp)
c0106a25:	e8 4e 99 ff ff       	call   c0100378 <cprintf>
                    *ptep = (page->pra_vaddr/PGSIZE+1)<<8;  // 更新页面表项，标记页面已交换到磁盘
c0106a2a:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106a2d:	8b 40 1c             	mov    0x1c(%eax),%eax
c0106a30:	c1 e8 0c             	shr    $0xc,%eax
c0106a33:	40                   	inc    %eax
c0106a34:	c1 e0 08             	shl    $0x8,%eax
c0106a37:	89 c2                	mov    %eax,%edx
c0106a39:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106a3c:	89 10                	mov    %edx,(%eax)
                    free_page(page);    // 释放页面
c0106a3e:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106a41:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0106a48:	00 
c0106a49:	89 04 24             	mov    %eax,(%esp)
c0106a4c:	e8 f7 e5 ff ff       	call   c0105048 <free_pages>
          }
          
          tlb_invalidate(mm->pgdir, v); // 使 TLB 中对应的条目失效
c0106a51:	8b 45 08             	mov    0x8(%ebp),%eax
c0106a54:	8b 40 0c             	mov    0xc(%eax),%eax
c0106a57:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0106a5a:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106a5e:	89 04 24             	mov    %eax,(%esp)
c0106a61:	e8 2c ef ff ff       	call   c0105992 <tlb_invalidate>
     for (i = 0; i != n; ++ i)// 循环 n 次，每次处理一个页面
c0106a66:	ff 45 f4             	incl   -0xc(%ebp)
c0106a69:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106a6c:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0106a6f:	0f 85 a1 fe ff ff    	jne    c0106916 <swap_out+0x12>
     }
     return i; // 返回实际交换出的页面数量
c0106a75:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0106a78:	89 ec                	mov    %ebp,%esp
c0106a7a:	5d                   	pop    %ebp
c0106a7b:	c3                   	ret    

c0106a7c <swap_in>:

//实现一个页交换功能。
int
swap_in(struct mm_struct *mm, uintptr_t addr, struct Page **ptr_result)
{
c0106a7c:	55                   	push   %ebp
c0106a7d:	89 e5                	mov    %esp,%ebp
c0106a7f:	83 ec 28             	sub    $0x28,%esp
     //分配一个新的页面result
     struct Page *result = alloc_page();
c0106a82:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0106a89:	e8 4d e5 ff ff       	call   c0104fdb <alloc_pages>
c0106a8e:	89 45 f4             	mov    %eax,-0xc(%ebp)
     assert(result!=NULL);
c0106a91:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0106a95:	75 24                	jne    c0106abb <swap_in+0x3f>
c0106a97:	c7 44 24 0c c8 b5 10 	movl   $0xc010b5c8,0xc(%esp)
c0106a9e:	c0 
c0106a9f:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106aa6:	c0 
c0106aa7:	c7 44 24 04 b3 00 00 	movl   $0xb3,0x4(%esp)
c0106aae:	00 
c0106aaf:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106ab6:	e8 8a a1 ff ff       	call   c0100c45 <__panic>
     //获取虚拟地址 addr 对应的页表项指针 ptep
     pte_t *ptep = get_pte(mm->pgdir, addr, 0);
c0106abb:	8b 45 08             	mov    0x8(%ebp),%eax
c0106abe:	8b 40 0c             	mov    0xc(%eax),%eax
c0106ac1:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0106ac8:	00 
c0106ac9:	8b 55 0c             	mov    0xc(%ebp),%edx
c0106acc:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106ad0:	89 04 24             	mov    %eax,(%esp)
c0106ad3:	e8 be eb ff ff       	call   c0105696 <get_pte>
c0106ad8:	89 45 f0             	mov    %eax,-0x10(%ebp)
     // cprintf("SWAP: load ptep %x swap entry %d to vaddr 0x%08x, page %x, No %d\n", ptep, (*ptep)>>8, addr, result, (result-pages));
    
     int r;
     //从交换文件中读取数据到新分配的页面 result 中
     if ((r = swapfs_read((*ptep), result)) != 0)
c0106adb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106ade:	8b 00                	mov    (%eax),%eax
c0106ae0:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0106ae3:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106ae7:	89 04 24             	mov    %eax,(%esp)
c0106aea:	e8 fc 1b 00 00       	call   c01086eb <swapfs_read>
c0106aef:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0106af2:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0106af6:	74 2a                	je     c0106b22 <swap_in+0xa6>
     {
        assert(r!=0);
c0106af8:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0106afc:	75 24                	jne    c0106b22 <swap_in+0xa6>
c0106afe:	c7 44 24 0c d5 b5 10 	movl   $0xc010b5d5,0xc(%esp)
c0106b05:	c0 
c0106b06:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106b0d:	c0 
c0106b0e:	c7 44 24 04 bc 00 00 	movl   $0xbc,0x4(%esp)
c0106b15:	00 
c0106b16:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106b1d:	e8 23 a1 ff ff       	call   c0100c45 <__panic>
     }
     cprintf("swap_in: load disk swap entry %d with swap_page in vadr 0x%x\n", (*ptep)>>8, addr);
c0106b22:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106b25:	8b 00                	mov    (%eax),%eax
c0106b27:	c1 e8 08             	shr    $0x8,%eax
c0106b2a:	89 c2                	mov    %eax,%edx
c0106b2c:	8b 45 0c             	mov    0xc(%ebp),%eax
c0106b2f:	89 44 24 08          	mov    %eax,0x8(%esp)
c0106b33:	89 54 24 04          	mov    %edx,0x4(%esp)
c0106b37:	c7 04 24 dc b5 10 c0 	movl   $0xc010b5dc,(%esp)
c0106b3e:	e8 35 98 ff ff       	call   c0100378 <cprintf>
     *ptr_result=result;
c0106b43:	8b 45 10             	mov    0x10(%ebp),%eax
c0106b46:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0106b49:	89 10                	mov    %edx,(%eax)
     return 0;
c0106b4b:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0106b50:	89 ec                	mov    %ebp,%esp
c0106b52:	5d                   	pop    %ebp
c0106b53:	c3                   	ret    

c0106b54 <check_content_set>:
 * 通过向特定内存地址写入数据，并检查页面故障次数是否符合预期，来验证页面管理机制的正确性。
 * 此函数没有输入参数和返回值。
 */
static inline void
check_content_set(void)
{
c0106b54:	55                   	push   %ebp
c0106b55:	89 e5                	mov    %esp,%ebp
c0106b57:	83 ec 18             	sub    $0x18,%esp
     *(unsigned char *)0x1000 = 0x0a;
c0106b5a:	b8 00 10 00 00       	mov    $0x1000,%eax
c0106b5f:	c6 00 0a             	movb   $0xa,(%eax)
     assert(pgfault_num==1);
c0106b62:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0106b67:	83 f8 01             	cmp    $0x1,%eax
c0106b6a:	74 24                	je     c0106b90 <check_content_set+0x3c>
c0106b6c:	c7 44 24 0c 1a b6 10 	movl   $0xc010b61a,0xc(%esp)
c0106b73:	c0 
c0106b74:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106b7b:	c0 
c0106b7c:	c7 44 24 04 cd 00 00 	movl   $0xcd,0x4(%esp)
c0106b83:	00 
c0106b84:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106b8b:	e8 b5 a0 ff ff       	call   c0100c45 <__panic>
     *(unsigned char *)0x1010 = 0x0a;
c0106b90:	b8 10 10 00 00       	mov    $0x1010,%eax
c0106b95:	c6 00 0a             	movb   $0xa,(%eax)
     assert(pgfault_num==1);
c0106b98:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0106b9d:	83 f8 01             	cmp    $0x1,%eax
c0106ba0:	74 24                	je     c0106bc6 <check_content_set+0x72>
c0106ba2:	c7 44 24 0c 1a b6 10 	movl   $0xc010b61a,0xc(%esp)
c0106ba9:	c0 
c0106baa:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106bb1:	c0 
c0106bb2:	c7 44 24 04 cf 00 00 	movl   $0xcf,0x4(%esp)
c0106bb9:	00 
c0106bba:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106bc1:	e8 7f a0 ff ff       	call   c0100c45 <__panic>
     *(unsigned char *)0x2000 = 0x0b;
c0106bc6:	b8 00 20 00 00       	mov    $0x2000,%eax
c0106bcb:	c6 00 0b             	movb   $0xb,(%eax)
     assert(pgfault_num==2);
c0106bce:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0106bd3:	83 f8 02             	cmp    $0x2,%eax
c0106bd6:	74 24                	je     c0106bfc <check_content_set+0xa8>
c0106bd8:	c7 44 24 0c 29 b6 10 	movl   $0xc010b629,0xc(%esp)
c0106bdf:	c0 
c0106be0:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106be7:	c0 
c0106be8:	c7 44 24 04 d1 00 00 	movl   $0xd1,0x4(%esp)
c0106bef:	00 
c0106bf0:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106bf7:	e8 49 a0 ff ff       	call   c0100c45 <__panic>
     *(unsigned char *)0x2010 = 0x0b;
c0106bfc:	b8 10 20 00 00       	mov    $0x2010,%eax
c0106c01:	c6 00 0b             	movb   $0xb,(%eax)
     assert(pgfault_num==2);
c0106c04:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0106c09:	83 f8 02             	cmp    $0x2,%eax
c0106c0c:	74 24                	je     c0106c32 <check_content_set+0xde>
c0106c0e:	c7 44 24 0c 29 b6 10 	movl   $0xc010b629,0xc(%esp)
c0106c15:	c0 
c0106c16:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106c1d:	c0 
c0106c1e:	c7 44 24 04 d3 00 00 	movl   $0xd3,0x4(%esp)
c0106c25:	00 
c0106c26:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106c2d:	e8 13 a0 ff ff       	call   c0100c45 <__panic>
     *(unsigned char *)0x3000 = 0x0c;
c0106c32:	b8 00 30 00 00       	mov    $0x3000,%eax
c0106c37:	c6 00 0c             	movb   $0xc,(%eax)
     assert(pgfault_num==3);
c0106c3a:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0106c3f:	83 f8 03             	cmp    $0x3,%eax
c0106c42:	74 24                	je     c0106c68 <check_content_set+0x114>
c0106c44:	c7 44 24 0c 38 b6 10 	movl   $0xc010b638,0xc(%esp)
c0106c4b:	c0 
c0106c4c:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106c53:	c0 
c0106c54:	c7 44 24 04 d5 00 00 	movl   $0xd5,0x4(%esp)
c0106c5b:	00 
c0106c5c:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106c63:	e8 dd 9f ff ff       	call   c0100c45 <__panic>
     *(unsigned char *)0x3010 = 0x0c;
c0106c68:	b8 10 30 00 00       	mov    $0x3010,%eax
c0106c6d:	c6 00 0c             	movb   $0xc,(%eax)
     assert(pgfault_num==3);
c0106c70:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0106c75:	83 f8 03             	cmp    $0x3,%eax
c0106c78:	74 24                	je     c0106c9e <check_content_set+0x14a>
c0106c7a:	c7 44 24 0c 38 b6 10 	movl   $0xc010b638,0xc(%esp)
c0106c81:	c0 
c0106c82:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106c89:	c0 
c0106c8a:	c7 44 24 04 d7 00 00 	movl   $0xd7,0x4(%esp)
c0106c91:	00 
c0106c92:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106c99:	e8 a7 9f ff ff       	call   c0100c45 <__panic>
     *(unsigned char *)0x4000 = 0x0d;
c0106c9e:	b8 00 40 00 00       	mov    $0x4000,%eax
c0106ca3:	c6 00 0d             	movb   $0xd,(%eax)
     assert(pgfault_num==4);
c0106ca6:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0106cab:	83 f8 04             	cmp    $0x4,%eax
c0106cae:	74 24                	je     c0106cd4 <check_content_set+0x180>
c0106cb0:	c7 44 24 0c 47 b6 10 	movl   $0xc010b647,0xc(%esp)
c0106cb7:	c0 
c0106cb8:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106cbf:	c0 
c0106cc0:	c7 44 24 04 d9 00 00 	movl   $0xd9,0x4(%esp)
c0106cc7:	00 
c0106cc8:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106ccf:	e8 71 9f ff ff       	call   c0100c45 <__panic>
     *(unsigned char *)0x4010 = 0x0d;
c0106cd4:	b8 10 40 00 00       	mov    $0x4010,%eax
c0106cd9:	c6 00 0d             	movb   $0xd,(%eax)
     assert(pgfault_num==4);
c0106cdc:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0106ce1:	83 f8 04             	cmp    $0x4,%eax
c0106ce4:	74 24                	je     c0106d0a <check_content_set+0x1b6>
c0106ce6:	c7 44 24 0c 47 b6 10 	movl   $0xc010b647,0xc(%esp)
c0106ced:	c0 
c0106cee:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106cf5:	c0 
c0106cf6:	c7 44 24 04 db 00 00 	movl   $0xdb,0x4(%esp)
c0106cfd:	00 
c0106cfe:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106d05:	e8 3b 9f ff ff       	call   c0100c45 <__panic>
}
c0106d0a:	90                   	nop
c0106d0b:	89 ec                	mov    %ebp,%esp
c0106d0d:	5d                   	pop    %ebp
c0106d0e:	c3                   	ret    

c0106d0f <check_content_access>:
 * 
 * @return int 返回权限检查的结果，非零表示成功，零表示失败
 */
static inline int
check_content_access(void)
{
c0106d0f:	55                   	push   %ebp
c0106d10:	89 e5                	mov    %esp,%ebp
c0106d12:	83 ec 18             	sub    $0x18,%esp
    // 调用swap管理器的检查方法，并将结果返回
    int ret = sm->check_swap();
c0106d15:	a1 60 c1 12 c0       	mov    0xc012c160,%eax
c0106d1a:	8b 40 1c             	mov    0x1c(%eax),%eax
c0106d1d:	ff d0                	call   *%eax
c0106d1f:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return ret;
c0106d22:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0106d25:	89 ec                	mov    %ebp,%esp
c0106d27:	5d                   	pop    %ebp
c0106d28:	c3                   	ret    

c0106d29 <check_swap>:
#define nr_free (free_area.nr_free)

// 检查交换机制的正确性，通过模拟页面替换算法
static void
check_swap(void)
{
c0106d29:	55                   	push   %ebp
c0106d2a:	89 e5                	mov    %esp,%ebp
c0106d2c:	83 ec 78             	sub    $0x78,%esp
    //backup mem env// 备份内存环境，确保检查后没有页面丢失
     int ret, count = 0, total = 0, i;
c0106d2f:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0106d36:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
     list_entry_t *le = &free_list;
c0106d3d:	c7 45 e8 e4 bf 12 c0 	movl   $0xc012bfe4,-0x18(%ebp)
     while ((le = list_next(le)) != &free_list) {
c0106d44:	eb 6a                	jmp    c0106db0 <check_swap+0x87>
        struct Page *p = le2page(le, page_link);// 将链表条目转换为页面结构
c0106d46:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106d49:	83 e8 0c             	sub    $0xc,%eax
c0106d4c:	89 45 c8             	mov    %eax,-0x38(%ebp)
        assert(PageProperty(p));// 断言页面属性有效
c0106d4f:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0106d52:	83 c0 04             	add    $0x4,%eax
c0106d55:	c7 45 c4 01 00 00 00 	movl   $0x1,-0x3c(%ebp)
c0106d5c:	89 45 c0             	mov    %eax,-0x40(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0106d5f:	8b 45 c0             	mov    -0x40(%ebp),%eax
c0106d62:	8b 55 c4             	mov    -0x3c(%ebp),%edx
c0106d65:	0f a3 10             	bt     %edx,(%eax)
c0106d68:	19 c0                	sbb    %eax,%eax
c0106d6a:	89 45 bc             	mov    %eax,-0x44(%ebp)
    return oldbit != 0;
c0106d6d:	83 7d bc 00          	cmpl   $0x0,-0x44(%ebp)
c0106d71:	0f 95 c0             	setne  %al
c0106d74:	0f b6 c0             	movzbl %al,%eax
c0106d77:	85 c0                	test   %eax,%eax
c0106d79:	75 24                	jne    c0106d9f <check_swap+0x76>
c0106d7b:	c7 44 24 0c 56 b6 10 	movl   $0xc010b656,0xc(%esp)
c0106d82:	c0 
c0106d83:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106d8a:	c0 
c0106d8b:	c7 44 24 04 00 01 00 	movl   $0x100,0x4(%esp)
c0106d92:	00 
c0106d93:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106d9a:	e8 a6 9e ff ff       	call   c0100c45 <__panic>
        count ++, total += p->property;// 统计页面数量和属性总和
c0106d9f:	ff 45 f4             	incl   -0xc(%ebp)
c0106da2:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0106da5:	8b 50 08             	mov    0x8(%eax),%edx
c0106da8:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106dab:	01 d0                	add    %edx,%eax
c0106dad:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0106db0:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0106db3:	89 45 b8             	mov    %eax,-0x48(%ebp)
c0106db6:	8b 45 b8             	mov    -0x48(%ebp),%eax
c0106db9:	8b 40 04             	mov    0x4(%eax),%eax
     while ((le = list_next(le)) != &free_list) {
c0106dbc:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0106dbf:	81 7d e8 e4 bf 12 c0 	cmpl   $0xc012bfe4,-0x18(%ebp)
c0106dc6:	0f 85 7a ff ff ff    	jne    c0106d46 <check_swap+0x1d>
     }
     assert(total == nr_free_pages());// 断言统计的属性总和与空闲页面数一致
c0106dcc:	e8 ac e2 ff ff       	call   c010507d <nr_free_pages>
c0106dd1:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0106dd4:	39 d0                	cmp    %edx,%eax
c0106dd6:	74 24                	je     c0106dfc <check_swap+0xd3>
c0106dd8:	c7 44 24 0c 66 b6 10 	movl   $0xc010b666,0xc(%esp)
c0106ddf:	c0 
c0106de0:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106de7:	c0 
c0106de8:	c7 44 24 04 03 01 00 	movl   $0x103,0x4(%esp)
c0106def:	00 
c0106df0:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106df7:	e8 49 9e ff ff       	call   c0100c45 <__panic>
     cprintf("BEGIN check_swap: count %d, total %d\n",count,total);// 打印初始状态
c0106dfc:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0106dff:	89 44 24 08          	mov    %eax,0x8(%esp)
c0106e03:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0106e06:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106e0a:	c7 04 24 80 b6 10 c0 	movl   $0xc010b680,(%esp)
c0106e11:	e8 62 95 ff ff       	call   c0100378 <cprintf>
     
     //now we set the phy pages env // 设置物理页面环境    
     struct mm_struct *mm = mm_create();// 创建内存管理结构
c0106e16:	e8 1e 0b 00 00       	call   c0107939 <mm_create>
c0106e1b:	89 45 e4             	mov    %eax,-0x1c(%ebp)
     assert(mm != NULL); // 断言内存管理结构创建成功
c0106e1e:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0106e22:	75 24                	jne    c0106e48 <check_swap+0x11f>
c0106e24:	c7 44 24 0c a6 b6 10 	movl   $0xc010b6a6,0xc(%esp)
c0106e2b:	c0 
c0106e2c:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106e33:	c0 
c0106e34:	c7 44 24 04 08 01 00 	movl   $0x108,0x4(%esp)
c0106e3b:	00 
c0106e3c:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106e43:	e8 fd 9d ff ff       	call   c0100c45 <__panic>

     extern struct mm_struct *check_mm_struct;// 声明外部变量
     assert(check_mm_struct == NULL);// 断言外部变量为空
c0106e48:	a1 6c c1 12 c0       	mov    0xc012c16c,%eax
c0106e4d:	85 c0                	test   %eax,%eax
c0106e4f:	74 24                	je     c0106e75 <check_swap+0x14c>
c0106e51:	c7 44 24 0c b1 b6 10 	movl   $0xc010b6b1,0xc(%esp)
c0106e58:	c0 
c0106e59:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106e60:	c0 
c0106e61:	c7 44 24 04 0b 01 00 	movl   $0x10b,0x4(%esp)
c0106e68:	00 
c0106e69:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106e70:	e8 d0 9d ff ff       	call   c0100c45 <__panic>

     // 将新创建的内存管理结构赋值给外部变量
     check_mm_struct = mm;
c0106e75:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106e78:	a3 6c c1 12 c0       	mov    %eax,0xc012c16c

     pde_t *pgdir = mm->pgdir = boot_pgdir;// 设置页目录
c0106e7d:	8b 15 00 8a 12 c0    	mov    0xc0128a00,%edx
c0106e83:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106e86:	89 50 0c             	mov    %edx,0xc(%eax)
c0106e89:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106e8c:	8b 40 0c             	mov    0xc(%eax),%eax
c0106e8f:	89 45 e0             	mov    %eax,-0x20(%ebp)
     assert(pgdir[0] == 0);// 断言页目录的第一个条目为空
c0106e92:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0106e95:	8b 00                	mov    (%eax),%eax
c0106e97:	85 c0                	test   %eax,%eax
c0106e99:	74 24                	je     c0106ebf <check_swap+0x196>
c0106e9b:	c7 44 24 0c c9 b6 10 	movl   $0xc010b6c9,0xc(%esp)
c0106ea2:	c0 
c0106ea3:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106eaa:	c0 
c0106eab:	c7 44 24 04 11 01 00 	movl   $0x111,0x4(%esp)
c0106eb2:	00 
c0106eb3:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106eba:	e8 86 9d ff ff       	call   c0100c45 <__panic>

     // 创建虚拟内存区域
     struct vma_struct *vma = vma_create(BEING_CHECK_VALID_VADDR, CHECK_VALID_VADDR, VM_WRITE | VM_READ);
c0106ebf:	c7 44 24 08 03 00 00 	movl   $0x3,0x8(%esp)
c0106ec6:	00 
c0106ec7:	c7 44 24 04 00 60 00 	movl   $0x6000,0x4(%esp)
c0106ece:	00 
c0106ecf:	c7 04 24 00 10 00 00 	movl   $0x1000,(%esp)
c0106ed6:	e8 d9 0a 00 00       	call   c01079b4 <vma_create>
c0106edb:	89 45 dc             	mov    %eax,-0x24(%ebp)
     assert(vma != NULL);// 断言虚拟内存区域创建成功
c0106ede:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0106ee2:	75 24                	jne    c0106f08 <check_swap+0x1df>
c0106ee4:	c7 44 24 0c d7 b6 10 	movl   $0xc010b6d7,0xc(%esp)
c0106eeb:	c0 
c0106eec:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106ef3:	c0 
c0106ef4:	c7 44 24 04 15 01 00 	movl   $0x115,0x4(%esp)
c0106efb:	00 
c0106efc:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106f03:	e8 3d 9d ff ff       	call   c0100c45 <__panic>

     // 插入虚拟内存区域到内存管理结构
     insert_vma_struct(mm, vma);
c0106f08:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0106f0b:	89 44 24 04          	mov    %eax,0x4(%esp)
c0106f0f:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106f12:	89 04 24             	mov    %eax,(%esp)
c0106f15:	e8 31 0c 00 00       	call   c0107b4b <insert_vma_struct>

     //setup the temp Page Table vaddr 0~4MB/ 设置临时页表，用于虚拟地址 0~4MB
     cprintf("setup Page Table for vaddr 0X1000, so alloc a page\n");// 打印设置页表的信息
c0106f1a:	c7 04 24 e4 b6 10 c0 	movl   $0xc010b6e4,(%esp)
c0106f21:	e8 52 94 ff ff       	call   c0100378 <cprintf>
     pte_t *temp_ptep=NULL;
c0106f26:	c7 45 d8 00 00 00 00 	movl   $0x0,-0x28(%ebp)
     temp_ptep = get_pte(mm->pgdir, BEING_CHECK_VALID_VADDR, 1);// 获取页表项
c0106f2d:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0106f30:	8b 40 0c             	mov    0xc(%eax),%eax
c0106f33:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c0106f3a:	00 
c0106f3b:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
c0106f42:	00 
c0106f43:	89 04 24             	mov    %eax,(%esp)
c0106f46:	e8 4b e7 ff ff       	call   c0105696 <get_pte>
c0106f4b:	89 45 d8             	mov    %eax,-0x28(%ebp)
     assert(temp_ptep!= NULL);// 断言获取页表项成功
c0106f4e:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
c0106f52:	75 24                	jne    c0106f78 <check_swap+0x24f>
c0106f54:	c7 44 24 0c 18 b7 10 	movl   $0xc010b718,0xc(%esp)
c0106f5b:	c0 
c0106f5c:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106f63:	c0 
c0106f64:	c7 44 24 04 1e 01 00 	movl   $0x11e,0x4(%esp)
c0106f6b:	00 
c0106f6c:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106f73:	e8 cd 9c ff ff       	call   c0100c45 <__panic>
     cprintf("setup Page Table vaddr 0~4MB OVER!\n");// 打印设置页表完成的信息
c0106f78:	c7 04 24 2c b7 10 c0 	movl   $0xc010b72c,(%esp)
c0106f7f:	e8 f4 93 ff ff       	call   c0100378 <cprintf>
     
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0106f84:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0106f8b:	e9 a2 00 00 00       	jmp    c0107032 <check_swap+0x309>
          check_rp[i] = alloc_page();// 分配页面
c0106f90:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0106f97:	e8 3f e0 ff ff       	call   c0104fdb <alloc_pages>
c0106f9c:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0106f9f:	89 04 95 2c c1 12 c0 	mov    %eax,-0x3fed3ed4(,%edx,4)
          assert(check_rp[i] != NULL );// 断言分配页面成功
c0106fa6:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106fa9:	8b 04 85 2c c1 12 c0 	mov    -0x3fed3ed4(,%eax,4),%eax
c0106fb0:	85 c0                	test   %eax,%eax
c0106fb2:	75 24                	jne    c0106fd8 <check_swap+0x2af>
c0106fb4:	c7 44 24 0c 50 b7 10 	movl   $0xc010b750,0xc(%esp)
c0106fbb:	c0 
c0106fbc:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0106fc3:	c0 
c0106fc4:	c7 44 24 04 23 01 00 	movl   $0x123,0x4(%esp)
c0106fcb:	00 
c0106fcc:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0106fd3:	e8 6d 9c ff ff       	call   c0100c45 <__panic>
          assert(!PageProperty(check_rp[i]));// 断言页面属性无效
c0106fd8:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0106fdb:	8b 04 85 2c c1 12 c0 	mov    -0x3fed3ed4(,%eax,4),%eax
c0106fe2:	83 c0 04             	add    $0x4,%eax
c0106fe5:	c7 45 b4 01 00 00 00 	movl   $0x1,-0x4c(%ebp)
c0106fec:	89 45 b0             	mov    %eax,-0x50(%ebp)
    asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr));
c0106fef:	8b 45 b0             	mov    -0x50(%ebp),%eax
c0106ff2:	8b 55 b4             	mov    -0x4c(%ebp),%edx
c0106ff5:	0f a3 10             	bt     %edx,(%eax)
c0106ff8:	19 c0                	sbb    %eax,%eax
c0106ffa:	89 45 ac             	mov    %eax,-0x54(%ebp)
    return oldbit != 0;
c0106ffd:	83 7d ac 00          	cmpl   $0x0,-0x54(%ebp)
c0107001:	0f 95 c0             	setne  %al
c0107004:	0f b6 c0             	movzbl %al,%eax
c0107007:	85 c0                	test   %eax,%eax
c0107009:	74 24                	je     c010702f <check_swap+0x306>
c010700b:	c7 44 24 0c 64 b7 10 	movl   $0xc010b764,0xc(%esp)
c0107012:	c0 
c0107013:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c010701a:	c0 
c010701b:	c7 44 24 04 24 01 00 	movl   $0x124,0x4(%esp)
c0107022:	00 
c0107023:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c010702a:	e8 16 9c ff ff       	call   c0100c45 <__panic>
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c010702f:	ff 45 ec             	incl   -0x14(%ebp)
c0107032:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c0107036:	0f 8e 54 ff ff ff    	jle    c0106f90 <check_swap+0x267>
     }
     list_entry_t free_list_store = free_list;// 保存当前空闲列表
c010703c:	a1 e4 bf 12 c0       	mov    0xc012bfe4,%eax
c0107041:	8b 15 e8 bf 12 c0    	mov    0xc012bfe8,%edx
c0107047:	89 45 98             	mov    %eax,-0x68(%ebp)
c010704a:	89 55 9c             	mov    %edx,-0x64(%ebp)
c010704d:	c7 45 a4 e4 bf 12 c0 	movl   $0xc012bfe4,-0x5c(%ebp)
    elm->prev = elm->next = elm;
c0107054:	8b 45 a4             	mov    -0x5c(%ebp),%eax
c0107057:	8b 55 a4             	mov    -0x5c(%ebp),%edx
c010705a:	89 50 04             	mov    %edx,0x4(%eax)
c010705d:	8b 45 a4             	mov    -0x5c(%ebp),%eax
c0107060:	8b 50 04             	mov    0x4(%eax),%edx
c0107063:	8b 45 a4             	mov    -0x5c(%ebp),%eax
c0107066:	89 10                	mov    %edx,(%eax)
}
c0107068:	90                   	nop
c0107069:	c7 45 a8 e4 bf 12 c0 	movl   $0xc012bfe4,-0x58(%ebp)
    return list->next == list;
c0107070:	8b 45 a8             	mov    -0x58(%ebp),%eax
c0107073:	8b 40 04             	mov    0x4(%eax),%eax
c0107076:	39 45 a8             	cmp    %eax,-0x58(%ebp)
c0107079:	0f 94 c0             	sete   %al
c010707c:	0f b6 c0             	movzbl %al,%eax
     list_init(&free_list);// 初始化空闲列表
     assert(list_empty(&free_list));// 断言空闲列表为空
c010707f:	85 c0                	test   %eax,%eax
c0107081:	75 24                	jne    c01070a7 <check_swap+0x37e>
c0107083:	c7 44 24 0c 7f b7 10 	movl   $0xc010b77f,0xc(%esp)
c010708a:	c0 
c010708b:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0107092:	c0 
c0107093:	c7 44 24 04 28 01 00 	movl   $0x128,0x4(%esp)
c010709a:	00 
c010709b:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c01070a2:	e8 9e 9b ff ff       	call   c0100c45 <__panic>
     
     //assert(alloc_page() == NULL);
     
     unsigned int nr_free_store = nr_free;// 保存当前空闲页面数
c01070a7:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
c01070ac:	89 45 d4             	mov    %eax,-0x2c(%ebp)
     nr_free = 0;// 将空闲页面数设为 0
c01070af:	c7 05 ec bf 12 c0 00 	movl   $0x0,0xc012bfec
c01070b6:	00 00 00 
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c01070b9:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c01070c0:	eb 1d                	jmp    c01070df <check_swap+0x3b6>
        free_pages(check_rp[i],1);// 释放页面
c01070c2:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01070c5:	8b 04 85 2c c1 12 c0 	mov    -0x3fed3ed4(,%eax,4),%eax
c01070cc:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01070d3:	00 
c01070d4:	89 04 24             	mov    %eax,(%esp)
c01070d7:	e8 6c df ff ff       	call   c0105048 <free_pages>
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c01070dc:	ff 45 ec             	incl   -0x14(%ebp)
c01070df:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c01070e3:	7e dd                	jle    c01070c2 <check_swap+0x399>
     }
     assert(nr_free==CHECK_VALID_PHY_PAGE_NUM);// 断言释放的页面数正确
c01070e5:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
c01070ea:	83 f8 04             	cmp    $0x4,%eax
c01070ed:	74 24                	je     c0107113 <check_swap+0x3ea>
c01070ef:	c7 44 24 0c 98 b7 10 	movl   $0xc010b798,0xc(%esp)
c01070f6:	c0 
c01070f7:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c01070fe:	c0 
c01070ff:	c7 44 24 04 31 01 00 	movl   $0x131,0x4(%esp)
c0107106:	00 
c0107107:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c010710e:	e8 32 9b ff ff       	call   c0100c45 <__panic>
     
     cprintf("set up init env for check_swap begin!\n");// 打印设置初始环境开始的信息
c0107113:	c7 04 24 bc b7 10 c0 	movl   $0xc010b7bc,(%esp)
c010711a:	e8 59 92 ff ff       	call   c0100378 <cprintf>
     //setup initial vir_page<->phy_page environment for page relpacement algorithm 
     // 设置初始虚拟到物理页面环境，用于页面替换算法
     
     pgfault_num=0;// 初始化页面故障数
c010711f:	c7 05 70 c1 12 c0 00 	movl   $0x0,0xc012c170
c0107126:	00 00 00 
     
     check_content_set();// 设置检查内容
c0107129:	e8 26 fa ff ff       	call   c0106b54 <check_content_set>
     assert( nr_free == 0);  // 断言空闲页面数为 0       
c010712e:	a1 ec bf 12 c0       	mov    0xc012bfec,%eax
c0107133:	85 c0                	test   %eax,%eax
c0107135:	74 24                	je     c010715b <check_swap+0x432>
c0107137:	c7 44 24 0c e3 b7 10 	movl   $0xc010b7e3,0xc(%esp)
c010713e:	c0 
c010713f:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0107146:	c0 
c0107147:	c7 44 24 04 3a 01 00 	movl   $0x13a,0x4(%esp)
c010714e:	00 
c010714f:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0107156:	e8 ea 9a ff ff       	call   c0100c45 <__panic>
     for(i = 0; i<MAX_SEQ_NO ; i++) 
c010715b:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0107162:	eb 25                	jmp    c0107189 <check_swap+0x460>
         swap_out_seq_no[i]=swap_in_seq_no[i]=-1;// 初始化页面替换序列号
c0107164:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107167:	c7 04 85 c0 c0 12 c0 	movl   $0xffffffff,-0x3fed3f40(,%eax,4)
c010716e:	ff ff ff ff 
c0107172:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107175:	8b 14 85 c0 c0 12 c0 	mov    -0x3fed3f40(,%eax,4),%edx
c010717c:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010717f:	89 14 85 00 c1 12 c0 	mov    %edx,-0x3fed3f00(,%eax,4)
     for(i = 0; i<MAX_SEQ_NO ; i++) 
c0107186:	ff 45 ec             	incl   -0x14(%ebp)
c0107189:	83 7d ec 09          	cmpl   $0x9,-0x14(%ebp)
c010718d:	7e d5                	jle    c0107164 <check_swap+0x43b>
     
     for (i= 0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c010718f:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c0107196:	e9 e8 00 00 00       	jmp    c0107283 <check_swap+0x55a>
         check_ptep[i]=0;
c010719b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010719e:	c7 04 85 3c c1 12 c0 	movl   $0x0,-0x3fed3ec4(,%eax,4)
c01071a5:	00 00 00 00 
         check_ptep[i] = get_pte(pgdir, (i+1)*0x1000, 0);// 获取页表项
c01071a9:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01071ac:	40                   	inc    %eax
c01071ad:	c1 e0 0c             	shl    $0xc,%eax
c01071b0:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01071b7:	00 
c01071b8:	89 44 24 04          	mov    %eax,0x4(%esp)
c01071bc:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01071bf:	89 04 24             	mov    %eax,(%esp)
c01071c2:	e8 cf e4 ff ff       	call   c0105696 <get_pte>
c01071c7:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01071ca:	89 04 95 3c c1 12 c0 	mov    %eax,-0x3fed3ec4(,%edx,4)
         //cprintf("i %d, check_ptep addr %x, value %x\n", i, check_ptep[i], *check_ptep[i]);
         assert(check_ptep[i] != NULL);// 断言获取页表项成功
c01071d1:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01071d4:	8b 04 85 3c c1 12 c0 	mov    -0x3fed3ec4(,%eax,4),%eax
c01071db:	85 c0                	test   %eax,%eax
c01071dd:	75 24                	jne    c0107203 <check_swap+0x4da>
c01071df:	c7 44 24 0c f0 b7 10 	movl   $0xc010b7f0,0xc(%esp)
c01071e6:	c0 
c01071e7:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c01071ee:	c0 
c01071ef:	c7 44 24 04 42 01 00 	movl   $0x142,0x4(%esp)
c01071f6:	00 
c01071f7:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c01071fe:	e8 42 9a ff ff       	call   c0100c45 <__panic>
         assert(pte2page(*check_ptep[i]) == check_rp[i]); // 断言页表项对应的页面正确
c0107203:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107206:	8b 04 85 3c c1 12 c0 	mov    -0x3fed3ec4(,%eax,4),%eax
c010720d:	8b 00                	mov    (%eax),%eax
c010720f:	89 04 24             	mov    %eax,(%esp)
c0107212:	e8 97 f5 ff ff       	call   c01067ae <pte2page>
c0107217:	8b 55 ec             	mov    -0x14(%ebp),%edx
c010721a:	8b 14 95 2c c1 12 c0 	mov    -0x3fed3ed4(,%edx,4),%edx
c0107221:	39 d0                	cmp    %edx,%eax
c0107223:	74 24                	je     c0107249 <check_swap+0x520>
c0107225:	c7 44 24 0c 08 b8 10 	movl   $0xc010b808,0xc(%esp)
c010722c:	c0 
c010722d:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c0107234:	c0 
c0107235:	c7 44 24 04 43 01 00 	movl   $0x143,0x4(%esp)
c010723c:	00 
c010723d:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c0107244:	e8 fc 99 ff ff       	call   c0100c45 <__panic>
         assert((*check_ptep[i] & PTE_P));  // 断言页表项有效        
c0107249:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010724c:	8b 04 85 3c c1 12 c0 	mov    -0x3fed3ec4(,%eax,4),%eax
c0107253:	8b 00                	mov    (%eax),%eax
c0107255:	83 e0 01             	and    $0x1,%eax
c0107258:	85 c0                	test   %eax,%eax
c010725a:	75 24                	jne    c0107280 <check_swap+0x557>
c010725c:	c7 44 24 0c 30 b8 10 	movl   $0xc010b830,0xc(%esp)
c0107263:	c0 
c0107264:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c010726b:	c0 
c010726c:	c7 44 24 04 44 01 00 	movl   $0x144,0x4(%esp)
c0107273:	00 
c0107274:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c010727b:	e8 c5 99 ff ff       	call   c0100c45 <__panic>
     for (i= 0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c0107280:	ff 45 ec             	incl   -0x14(%ebp)
c0107283:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c0107287:	0f 8e 0e ff ff ff    	jle    c010719b <check_swap+0x472>
     }
     cprintf("set up init env for check_swap over!\n");// 打印设置初始环境完成的信息
c010728d:	c7 04 24 4c b8 10 c0 	movl   $0xc010b84c,(%esp)
c0107294:	e8 df 90 ff ff       	call   c0100378 <cprintf>
     // now access the virt pages to test  page relpacement algorithm 
     ret=check_content_access();
c0107299:	e8 71 fa ff ff       	call   c0106d0f <check_content_access>
c010729e:	89 45 d0             	mov    %eax,-0x30(%ebp)
     assert(ret==0); // 断言访问检查成功
c01072a1:	83 7d d0 00          	cmpl   $0x0,-0x30(%ebp)
c01072a5:	74 24                	je     c01072cb <check_swap+0x5a2>
c01072a7:	c7 44 24 0c 72 b8 10 	movl   $0xc010b872,0xc(%esp)
c01072ae:	c0 
c01072af:	c7 44 24 08 5a b5 10 	movl   $0xc010b55a,0x8(%esp)
c01072b6:	c0 
c01072b7:	c7 44 24 04 49 01 00 	movl   $0x149,0x4(%esp)
c01072be:	00 
c01072bf:	c7 04 24 f4 b4 10 c0 	movl   $0xc010b4f4,(%esp)
c01072c6:	e8 7a 99 ff ff       	call   c0100c45 <__panic>
     
     //restore kernel mem env
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c01072cb:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
c01072d2:	eb 1d                	jmp    c01072f1 <check_swap+0x5c8>
         free_pages(check_rp[i],1);
c01072d4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01072d7:	8b 04 85 2c c1 12 c0 	mov    -0x3fed3ed4(,%eax,4),%eax
c01072de:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c01072e5:	00 
c01072e6:	89 04 24             	mov    %eax,(%esp)
c01072e9:	e8 5a dd ff ff       	call   c0105048 <free_pages>
     for (i=0;i<CHECK_VALID_PHY_PAGE_NUM;i++) {
c01072ee:	ff 45 ec             	incl   -0x14(%ebp)
c01072f1:	83 7d ec 03          	cmpl   $0x3,-0x14(%ebp)
c01072f5:	7e dd                	jle    c01072d4 <check_swap+0x5ab>
     } 

     //free_page(pte2page(*temp_ptep));
     
     mm_destroy(mm);// 销毁内存管理结构
c01072f7:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01072fa:	89 04 24             	mov    %eax,(%esp)
c01072fd:	e8 7f 09 00 00       	call   c0107c81 <mm_destroy>
         
     nr_free = nr_free_store;// 恢复空闲页面数
c0107302:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0107305:	a3 ec bf 12 c0       	mov    %eax,0xc012bfec
     free_list = free_list_store;// 恢复空闲列表
c010730a:	8b 45 98             	mov    -0x68(%ebp),%eax
c010730d:	8b 55 9c             	mov    -0x64(%ebp),%edx
c0107310:	a3 e4 bf 12 c0       	mov    %eax,0xc012bfe4
c0107315:	89 15 e8 bf 12 c0    	mov    %edx,0xc012bfe8

     
     le = &free_list;
c010731b:	c7 45 e8 e4 bf 12 c0 	movl   $0xc012bfe4,-0x18(%ebp)
     while ((le = list_next(le)) != &free_list) {
c0107322:	eb 1c                	jmp    c0107340 <check_swap+0x617>
         struct Page *p = le2page(le, page_link);// 将链表条目转换为页面结构
c0107324:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107327:	83 e8 0c             	sub    $0xc,%eax
c010732a:	89 45 cc             	mov    %eax,-0x34(%ebp)
         count --, total -= p->property;// 更新页面数量和属性总和
c010732d:	ff 4d f4             	decl   -0xc(%ebp)
c0107330:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0107333:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0107336:	8b 48 08             	mov    0x8(%eax),%ecx
c0107339:	89 d0                	mov    %edx,%eax
c010733b:	29 c8                	sub    %ecx,%eax
c010733d:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0107340:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107343:	89 45 a0             	mov    %eax,-0x60(%ebp)
    return listelm->next;
c0107346:	8b 45 a0             	mov    -0x60(%ebp),%eax
c0107349:	8b 40 04             	mov    0x4(%eax),%eax
     while ((le = list_next(le)) != &free_list) {
c010734c:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010734f:	81 7d e8 e4 bf 12 c0 	cmpl   $0xc012bfe4,-0x18(%ebp)
c0107356:	75 cc                	jne    c0107324 <check_swap+0x5fb>
     }
     cprintf("count is %d, total is %d\n",count,total);// 打印恢复后的状态
c0107358:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010735b:	89 44 24 08          	mov    %eax,0x8(%esp)
c010735f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107362:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107366:	c7 04 24 79 b8 10 c0 	movl   $0xc010b879,(%esp)
c010736d:	e8 06 90 ff ff       	call   c0100378 <cprintf>
     //assert(count == 0);
     
     cprintf("check_swap() succeeded!\n");// 打印检查成功的信息
c0107372:	c7 04 24 93 b8 10 c0 	movl   $0xc010b893,(%esp)
c0107379:	e8 fa 8f ff ff       	call   c0100378 <cprintf>
}
c010737e:	90                   	nop
c010737f:	89 ec                	mov    %ebp,%esp
c0107381:	5d                   	pop    %ebp
c0107382:	c3                   	ret    

c0107383 <_fifo_init_mm>:
 * (2) _fifo_init_mm: init pra_list_head and let  mm->sm_priv point to the addr of pra_list_head.
 *              Now, From the memory control struct mm_struct, we can access FIFO PRA
 */
static int
_fifo_init_mm(struct mm_struct *mm)
{     
c0107383:	55                   	push   %ebp
c0107384:	89 e5                	mov    %esp,%ebp
c0107386:	83 ec 10             	sub    $0x10,%esp
c0107389:	c7 45 fc 64 c1 12 c0 	movl   $0xc012c164,-0x4(%ebp)
    elm->prev = elm->next = elm;
c0107390:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0107393:	8b 55 fc             	mov    -0x4(%ebp),%edx
c0107396:	89 50 04             	mov    %edx,0x4(%eax)
c0107399:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010739c:	8b 50 04             	mov    0x4(%eax),%edx
c010739f:	8b 45 fc             	mov    -0x4(%ebp),%eax
c01073a2:	89 10                	mov    %edx,(%eax)
}
c01073a4:	90                   	nop
    //初始化一个链表头 pra_list_head
     list_init(&pra_list_head);
     //将 mm 结构中的 sm_priv 字段指向这个链表头
     mm->sm_priv = &pra_list_head;
c01073a5:	8b 45 08             	mov    0x8(%ebp),%eax
c01073a8:	c7 40 14 64 c1 12 c0 	movl   $0xc012c164,0x14(%eax)
     //cprintf(" mm->sm_priv %x in fifo_init_mm\n",mm->sm_priv);
     //返回 0 表示成功
     return 0;
c01073af:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01073b4:	89 ec                	mov    %ebp,%esp
c01073b6:	5d                   	pop    %ebp
c01073b7:	c3                   	ret    

c01073b8 <_fifo_map_swappable>:
/*
 * (3)_fifo_map_swappable: According FIFO PRA, we should link the most recent arrival page at the back of pra_list_head qeueue
 */
static int
_fifo_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in)
{
c01073b8:	55                   	push   %ebp
c01073b9:	89 e5                	mov    %esp,%ebp
c01073bb:	83 ec 48             	sub    $0x48,%esp
    //获取 mm_struct 结构中的 sm_priv 指针，
    //并将其转换为 list_entry_t 类型的链表头指针 head
    list_entry_t *head=(list_entry_t*) mm->sm_priv;
c01073be:	8b 45 08             	mov    0x8(%ebp),%eax
c01073c1:	8b 40 14             	mov    0x14(%eax),%eax
c01073c4:	89 45 f4             	mov    %eax,-0xc(%ebp)
    list_entry_t *entry=&(page->pra_page_link);
c01073c7:	8b 45 10             	mov    0x10(%ebp),%eax
c01073ca:	83 c0 14             	add    $0x14,%eax
c01073cd:	89 45 f0             	mov    %eax,-0x10(%ebp)
 
    assert(entry != NULL && head != NULL);
c01073d0:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01073d4:	74 06                	je     c01073dc <_fifo_map_swappable+0x24>
c01073d6:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01073da:	75 24                	jne    c0107400 <_fifo_map_swappable+0x48>
c01073dc:	c7 44 24 0c ac b8 10 	movl   $0xc010b8ac,0xc(%esp)
c01073e3:	c0 
c01073e4:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c01073eb:	c0 
c01073ec:	c7 44 24 04 37 00 00 	movl   $0x37,0x4(%esp)
c01073f3:	00 
c01073f4:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c01073fb:	e8 45 98 ff ff       	call   c0100c45 <__panic>
c0107400:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107403:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0107406:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107409:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010740c:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010740f:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0107412:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107415:	89 45 e0             	mov    %eax,-0x20(%ebp)
    __list_add(elm, listelm, listelm->next);
c0107418:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010741b:	8b 40 04             	mov    0x4(%eax),%eax
c010741e:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0107421:	89 55 dc             	mov    %edx,-0x24(%ebp)
c0107424:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0107427:	89 55 d8             	mov    %edx,-0x28(%ebp)
c010742a:	89 45 d4             	mov    %eax,-0x2c(%ebp)
    prev->next = next->prev = elm;
c010742d:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0107430:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0107433:	89 10                	mov    %edx,(%eax)
c0107435:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0107438:	8b 10                	mov    (%eax),%edx
c010743a:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010743d:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c0107440:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0107443:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0107446:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0107449:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010744c:	8b 55 d8             	mov    -0x28(%ebp),%edx
c010744f:	89 10                	mov    %edx,(%eax)
}
c0107451:	90                   	nop
}
c0107452:	90                   	nop
}
c0107453:	90                   	nop
    //record the page access situlation
    /*LAB3 EXERCISE 2: YOUR CODE*/ 
    //(1)link the most recent arrival page at the back of the pra_list_head qeueue.
    //将最近到达的页面链接到 pra_list_head 队列的末尾
    list_add(head, entry);
    return 0;
c0107454:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0107459:	89 ec                	mov    %ebp,%esp
c010745b:	5d                   	pop    %ebp
c010745c:	c3                   	ret    

c010745d <_fifo_swap_out_victim>:
 * 
 * @return 返回0表示成功，其他值表示失败。
 */
static int
_fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick)
{
c010745d:	55                   	push   %ebp
c010745e:	89 e5                	mov    %esp,%ebp
c0107460:	83 ec 38             	sub    $0x38,%esp
     list_entry_t *head=(list_entry_t*) mm->sm_priv;
c0107463:	8b 45 08             	mov    0x8(%ebp),%eax
c0107466:	8b 40 14             	mov    0x14(%eax),%eax
c0107469:	89 45 f4             	mov    %eax,-0xc(%ebp)
         assert(head != NULL);
c010746c:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0107470:	75 24                	jne    c0107496 <_fifo_swap_out_victim+0x39>
c0107472:	c7 44 24 0c f3 b8 10 	movl   $0xc010b8f3,0xc(%esp)
c0107479:	c0 
c010747a:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c0107481:	c0 
c0107482:	c7 44 24 04 50 00 00 	movl   $0x50,0x4(%esp)
c0107489:	00 
c010748a:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c0107491:	e8 af 97 ff ff       	call   c0100c45 <__panic>
     assert(in_tick==0);
c0107496:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c010749a:	74 24                	je     c01074c0 <_fifo_swap_out_victim+0x63>
c010749c:	c7 44 24 0c 00 b9 10 	movl   $0xc010b900,0xc(%esp)
c01074a3:	c0 
c01074a4:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c01074ab:	c0 
c01074ac:	c7 44 24 04 51 00 00 	movl   $0x51,0x4(%esp)
c01074b3:	00 
c01074b4:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c01074bb:	e8 85 97 ff ff       	call   c0100c45 <__panic>
     /* Select the victim */
     /*LAB3 EXERCISE 2: YOUR CODE*/ 
     //(1)  unlink the  earliest arrival page in front of pra_list_head qeueue
     //(2)  assign the value of *ptr_page to the addr of this page
     //head->prev 获取链表中最先到达的页面
     list_entry_t *le = head->prev;
c01074c0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01074c3:	8b 00                	mov    (%eax),%eax
c01074c5:	89 45 f0             	mov    %eax,-0x10(%ebp)
     assert(head!=le);
c01074c8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01074cb:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c01074ce:	75 24                	jne    c01074f4 <_fifo_swap_out_victim+0x97>
c01074d0:	c7 44 24 0c 0b b9 10 	movl   $0xc010b90b,0xc(%esp)
c01074d7:	c0 
c01074d8:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c01074df:	c0 
c01074e0:	c7 44 24 04 58 00 00 	movl   $0x58,0x4(%esp)
c01074e7:	00 
c01074e8:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c01074ef:	e8 51 97 ff ff       	call   c0100c45 <__panic>
     struct Page *p = le2page(le, pra_page_link);
c01074f4:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01074f7:	83 e8 14             	sub    $0x14,%eax
c01074fa:	89 45 ec             	mov    %eax,-0x14(%ebp)
c01074fd:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107500:	89 45 e8             	mov    %eax,-0x18(%ebp)
    __list_del(listelm->prev, listelm->next);
c0107503:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107506:	8b 40 04             	mov    0x4(%eax),%eax
c0107509:	8b 55 e8             	mov    -0x18(%ebp),%edx
c010750c:	8b 12                	mov    (%edx),%edx
c010750e:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c0107511:	89 45 e0             	mov    %eax,-0x20(%ebp)
    prev->next = next;
c0107514:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107517:	8b 55 e0             	mov    -0x20(%ebp),%edx
c010751a:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c010751d:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0107520:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0107523:	89 10                	mov    %edx,(%eax)
}
c0107525:	90                   	nop
}
c0107526:	90                   	nop
     //使用 list_del 函数将该页面从链表中移除。
     list_del(le);
     assert(p != NULL);
c0107527:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c010752b:	75 24                	jne    c0107551 <_fifo_swap_out_victim+0xf4>
c010752d:	c7 44 24 0c 14 b9 10 	movl   $0xc010b914,0xc(%esp)
c0107534:	c0 
c0107535:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c010753c:	c0 
c010753d:	c7 44 24 04 5c 00 00 	movl   $0x5c,0x4(%esp)
c0107544:	00 
c0107545:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c010754c:	e8 f4 96 ff ff       	call   c0100c45 <__panic>
     //将移除的页面指针赋值给 *ptr_page
     *ptr_page = p;
c0107551:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107554:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0107557:	89 10                	mov    %edx,(%eax)
     
     return 0;
c0107559:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010755e:	89 ec                	mov    %ebp,%esp
c0107560:	5d                   	pop    %ebp
c0107561:	c3                   	ret    

c0107562 <_fifo_check_swap>:
 * 
 * 返回值:
 * - 0: 表示所有检查均通过。
 */
static int
_fifo_check_swap(void) {
c0107562:	55                   	push   %ebp
c0107563:	89 e5                	mov    %esp,%ebp
c0107565:	83 ec 18             	sub    $0x18,%esp
    // 写入虚拟页 c 并检查页面故障数
    cprintf("write Virt Page c in fifo_check_swap\n");
c0107568:	c7 04 24 20 b9 10 c0 	movl   $0xc010b920,(%esp)
c010756f:	e8 04 8e ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x3000 = 0x0c;
c0107574:	b8 00 30 00 00       	mov    $0x3000,%eax
c0107579:	c6 00 0c             	movb   $0xc,(%eax)
    assert(pgfault_num==4);
c010757c:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0107581:	83 f8 04             	cmp    $0x4,%eax
c0107584:	74 24                	je     c01075aa <_fifo_check_swap+0x48>
c0107586:	c7 44 24 0c 46 b9 10 	movl   $0xc010b946,0xc(%esp)
c010758d:	c0 
c010758e:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c0107595:	c0 
c0107596:	c7 44 24 04 70 00 00 	movl   $0x70,0x4(%esp)
c010759d:	00 
c010759e:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c01075a5:	e8 9b 96 ff ff       	call   c0100c45 <__panic>

    // 写入虚拟页 a 并检查页面故障数
    cprintf("write Virt Page a in fifo_check_swap\n");
c01075aa:	c7 04 24 58 b9 10 c0 	movl   $0xc010b958,(%esp)
c01075b1:	e8 c2 8d ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x1000 = 0x0a;
c01075b6:	b8 00 10 00 00       	mov    $0x1000,%eax
c01075bb:	c6 00 0a             	movb   $0xa,(%eax)
    assert(pgfault_num==4);
c01075be:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c01075c3:	83 f8 04             	cmp    $0x4,%eax
c01075c6:	74 24                	je     c01075ec <_fifo_check_swap+0x8a>
c01075c8:	c7 44 24 0c 46 b9 10 	movl   $0xc010b946,0xc(%esp)
c01075cf:	c0 
c01075d0:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c01075d7:	c0 
c01075d8:	c7 44 24 04 75 00 00 	movl   $0x75,0x4(%esp)
c01075df:	00 
c01075e0:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c01075e7:	e8 59 96 ff ff       	call   c0100c45 <__panic>

    // 写入虚拟页 d 并检查页面故障数
    cprintf("write Virt Page d in fifo_check_swap\n");
c01075ec:	c7 04 24 80 b9 10 c0 	movl   $0xc010b980,(%esp)
c01075f3:	e8 80 8d ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x4000 = 0x0d;
c01075f8:	b8 00 40 00 00       	mov    $0x4000,%eax
c01075fd:	c6 00 0d             	movb   $0xd,(%eax)
    assert(pgfault_num==4);
c0107600:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0107605:	83 f8 04             	cmp    $0x4,%eax
c0107608:	74 24                	je     c010762e <_fifo_check_swap+0xcc>
c010760a:	c7 44 24 0c 46 b9 10 	movl   $0xc010b946,0xc(%esp)
c0107611:	c0 
c0107612:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c0107619:	c0 
c010761a:	c7 44 24 04 7a 00 00 	movl   $0x7a,0x4(%esp)
c0107621:	00 
c0107622:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c0107629:	e8 17 96 ff ff       	call   c0100c45 <__panic>

    // 写入虚拟页 b 并检查页面故障数
    cprintf("write Virt Page b in fifo_check_swap\n");
c010762e:	c7 04 24 a8 b9 10 c0 	movl   $0xc010b9a8,(%esp)
c0107635:	e8 3e 8d ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x2000 = 0x0b;
c010763a:	b8 00 20 00 00       	mov    $0x2000,%eax
c010763f:	c6 00 0b             	movb   $0xb,(%eax)
    assert(pgfault_num==4);
c0107642:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0107647:	83 f8 04             	cmp    $0x4,%eax
c010764a:	74 24                	je     c0107670 <_fifo_check_swap+0x10e>
c010764c:	c7 44 24 0c 46 b9 10 	movl   $0xc010b946,0xc(%esp)
c0107653:	c0 
c0107654:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c010765b:	c0 
c010765c:	c7 44 24 04 7f 00 00 	movl   $0x7f,0x4(%esp)
c0107663:	00 
c0107664:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c010766b:	e8 d5 95 ff ff       	call   c0100c45 <__panic>

    // 写入虚拟页 e 并检查页面故障数
    cprintf("write Virt Page e in fifo_check_swap\n");
c0107670:	c7 04 24 d0 b9 10 c0 	movl   $0xc010b9d0,(%esp)
c0107677:	e8 fc 8c ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x5000 = 0x0e;
c010767c:	b8 00 50 00 00       	mov    $0x5000,%eax
c0107681:	c6 00 0e             	movb   $0xe,(%eax)
    assert(pgfault_num==5);
c0107684:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0107689:	83 f8 05             	cmp    $0x5,%eax
c010768c:	74 24                	je     c01076b2 <_fifo_check_swap+0x150>
c010768e:	c7 44 24 0c f6 b9 10 	movl   $0xc010b9f6,0xc(%esp)
c0107695:	c0 
c0107696:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c010769d:	c0 
c010769e:	c7 44 24 04 84 00 00 	movl   $0x84,0x4(%esp)
c01076a5:	00 
c01076a6:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c01076ad:	e8 93 95 ff ff       	call   c0100c45 <__panic>

    // 再次写入虚拟页 b 并检查页面故障数
    cprintf("write Virt Page b in fifo_check_swap\n");
c01076b2:	c7 04 24 a8 b9 10 c0 	movl   $0xc010b9a8,(%esp)
c01076b9:	e8 ba 8c ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x2000 = 0x0b;
c01076be:	b8 00 20 00 00       	mov    $0x2000,%eax
c01076c3:	c6 00 0b             	movb   $0xb,(%eax)
    assert(pgfault_num==5);
c01076c6:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c01076cb:	83 f8 05             	cmp    $0x5,%eax
c01076ce:	74 24                	je     c01076f4 <_fifo_check_swap+0x192>
c01076d0:	c7 44 24 0c f6 b9 10 	movl   $0xc010b9f6,0xc(%esp)
c01076d7:	c0 
c01076d8:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c01076df:	c0 
c01076e0:	c7 44 24 04 89 00 00 	movl   $0x89,0x4(%esp)
c01076e7:	00 
c01076e8:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c01076ef:	e8 51 95 ff ff       	call   c0100c45 <__panic>

    // 再次写入虚拟页 a 并检查页面故障数
    cprintf("write Virt Page a in fifo_check_swap\n");
c01076f4:	c7 04 24 58 b9 10 c0 	movl   $0xc010b958,(%esp)
c01076fb:	e8 78 8c ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x1000 = 0x0a;
c0107700:	b8 00 10 00 00       	mov    $0x1000,%eax
c0107705:	c6 00 0a             	movb   $0xa,(%eax)
    assert(pgfault_num==6);
c0107708:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c010770d:	83 f8 06             	cmp    $0x6,%eax
c0107710:	74 24                	je     c0107736 <_fifo_check_swap+0x1d4>
c0107712:	c7 44 24 0c 05 ba 10 	movl   $0xc010ba05,0xc(%esp)
c0107719:	c0 
c010771a:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c0107721:	c0 
c0107722:	c7 44 24 04 8e 00 00 	movl   $0x8e,0x4(%esp)
c0107729:	00 
c010772a:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c0107731:	e8 0f 95 ff ff       	call   c0100c45 <__panic>

    // 再次写入虚拟页 b 并检查页面故障数
    cprintf("write Virt Page b in fifo_check_swap\n");
c0107736:	c7 04 24 a8 b9 10 c0 	movl   $0xc010b9a8,(%esp)
c010773d:	e8 36 8c ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x2000 = 0x0b;
c0107742:	b8 00 20 00 00       	mov    $0x2000,%eax
c0107747:	c6 00 0b             	movb   $0xb,(%eax)
    assert(pgfault_num==7);
c010774a:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c010774f:	83 f8 07             	cmp    $0x7,%eax
c0107752:	74 24                	je     c0107778 <_fifo_check_swap+0x216>
c0107754:	c7 44 24 0c 14 ba 10 	movl   $0xc010ba14,0xc(%esp)
c010775b:	c0 
c010775c:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c0107763:	c0 
c0107764:	c7 44 24 04 93 00 00 	movl   $0x93,0x4(%esp)
c010776b:	00 
c010776c:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c0107773:	e8 cd 94 ff ff       	call   c0100c45 <__panic>

    // 再次写入虚拟页 c 并检查页面故障数
    cprintf("write Virt Page c in fifo_check_swap\n");
c0107778:	c7 04 24 20 b9 10 c0 	movl   $0xc010b920,(%esp)
c010777f:	e8 f4 8b ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x3000 = 0x0c;
c0107784:	b8 00 30 00 00       	mov    $0x3000,%eax
c0107789:	c6 00 0c             	movb   $0xc,(%eax)
    assert(pgfault_num==8);
c010778c:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0107791:	83 f8 08             	cmp    $0x8,%eax
c0107794:	74 24                	je     c01077ba <_fifo_check_swap+0x258>
c0107796:	c7 44 24 0c 23 ba 10 	movl   $0xc010ba23,0xc(%esp)
c010779d:	c0 
c010779e:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c01077a5:	c0 
c01077a6:	c7 44 24 04 98 00 00 	movl   $0x98,0x4(%esp)
c01077ad:	00 
c01077ae:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c01077b5:	e8 8b 94 ff ff       	call   c0100c45 <__panic>

    // 再次写入虚拟页 d 并检查页面故障数
    cprintf("write Virt Page d in fifo_check_swap\n");
c01077ba:	c7 04 24 80 b9 10 c0 	movl   $0xc010b980,(%esp)
c01077c1:	e8 b2 8b ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x4000 = 0x0d;
c01077c6:	b8 00 40 00 00       	mov    $0x4000,%eax
c01077cb:	c6 00 0d             	movb   $0xd,(%eax)
    assert(pgfault_num==9);
c01077ce:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c01077d3:	83 f8 09             	cmp    $0x9,%eax
c01077d6:	74 24                	je     c01077fc <_fifo_check_swap+0x29a>
c01077d8:	c7 44 24 0c 32 ba 10 	movl   $0xc010ba32,0xc(%esp)
c01077df:	c0 
c01077e0:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c01077e7:	c0 
c01077e8:	c7 44 24 04 9d 00 00 	movl   $0x9d,0x4(%esp)
c01077ef:	00 
c01077f0:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c01077f7:	e8 49 94 ff ff       	call   c0100c45 <__panic>

     // 再次写入虚拟页 e 并检查页面故障数
    cprintf("write Virt Page e in fifo_check_swap\n");
c01077fc:	c7 04 24 d0 b9 10 c0 	movl   $0xc010b9d0,(%esp)
c0107803:	e8 70 8b ff ff       	call   c0100378 <cprintf>
    *(unsigned char *)0x5000 = 0x0e;
c0107808:	b8 00 50 00 00       	mov    $0x5000,%eax
c010780d:	c6 00 0e             	movb   $0xe,(%eax)
    assert(pgfault_num==10);
c0107810:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0107815:	83 f8 0a             	cmp    $0xa,%eax
c0107818:	74 24                	je     c010783e <_fifo_check_swap+0x2dc>
c010781a:	c7 44 24 0c 41 ba 10 	movl   $0xc010ba41,0xc(%esp)
c0107821:	c0 
c0107822:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c0107829:	c0 
c010782a:	c7 44 24 04 a2 00 00 	movl   $0xa2,0x4(%esp)
c0107831:	00 
c0107832:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c0107839:	e8 07 94 ff ff       	call   c0100c45 <__panic>

    // 再次写入虚拟页 a 并检查页面故障数
    cprintf("write Virt Page a in fifo_check_swap\n");
c010783e:	c7 04 24 58 b9 10 c0 	movl   $0xc010b958,(%esp)
c0107845:	e8 2e 8b ff ff       	call   c0100378 <cprintf>
    assert(*(unsigned char *)0x1000 == 0x0a);
c010784a:	b8 00 10 00 00       	mov    $0x1000,%eax
c010784f:	0f b6 00             	movzbl (%eax),%eax
c0107852:	3c 0a                	cmp    $0xa,%al
c0107854:	74 24                	je     c010787a <_fifo_check_swap+0x318>
c0107856:	c7 44 24 0c 54 ba 10 	movl   $0xc010ba54,0xc(%esp)
c010785d:	c0 
c010785e:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c0107865:	c0 
c0107866:	c7 44 24 04 a6 00 00 	movl   $0xa6,0x4(%esp)
c010786d:	00 
c010786e:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c0107875:	e8 cb 93 ff ff       	call   c0100c45 <__panic>
    *(unsigned char *)0x1000 = 0x0a;
c010787a:	b8 00 10 00 00       	mov    $0x1000,%eax
c010787f:	c6 00 0a             	movb   $0xa,(%eax)
    assert(pgfault_num==11);
c0107882:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c0107887:	83 f8 0b             	cmp    $0xb,%eax
c010788a:	74 24                	je     c01078b0 <_fifo_check_swap+0x34e>
c010788c:	c7 44 24 0c 75 ba 10 	movl   $0xc010ba75,0xc(%esp)
c0107893:	c0 
c0107894:	c7 44 24 08 ca b8 10 	movl   $0xc010b8ca,0x8(%esp)
c010789b:	c0 
c010789c:	c7 44 24 04 a8 00 00 	movl   $0xa8,0x4(%esp)
c01078a3:	00 
c01078a4:	c7 04 24 df b8 10 c0 	movl   $0xc010b8df,(%esp)
c01078ab:	e8 95 93 ff ff       	call   c0100c45 <__panic>
    return 0;
c01078b0:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01078b5:	89 ec                	mov    %ebp,%esp
c01078b7:	5d                   	pop    %ebp
c01078b8:	c3                   	ret    

c01078b9 <_fifo_init>:


static int
_fifo_init(void)
{
c01078b9:	55                   	push   %ebp
c01078ba:	89 e5                	mov    %esp,%ebp
    return 0;
c01078bc:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01078c1:	5d                   	pop    %ebp
c01078c2:	c3                   	ret    

c01078c3 <_fifo_set_unswappable>:

static int
_fifo_set_unswappable(struct mm_struct *mm, uintptr_t addr)
{
c01078c3:	55                   	push   %ebp
c01078c4:	89 e5                	mov    %esp,%ebp
    return 0;
c01078c6:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01078cb:	5d                   	pop    %ebp
c01078cc:	c3                   	ret    

c01078cd <_fifo_tick_event>:

static int
_fifo_tick_event(struct mm_struct *mm)
{ return 0; }
c01078cd:	55                   	push   %ebp
c01078ce:	89 e5                	mov    %esp,%ebp
c01078d0:	b8 00 00 00 00       	mov    $0x0,%eax
c01078d5:	5d                   	pop    %ebp
c01078d6:	c3                   	ret    

c01078d7 <pa2page>:
pa2page(uintptr_t pa) {
c01078d7:	55                   	push   %ebp
c01078d8:	89 e5                	mov    %esp,%ebp
c01078da:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c01078dd:	8b 45 08             	mov    0x8(%ebp),%eax
c01078e0:	c1 e8 0c             	shr    $0xc,%eax
c01078e3:	89 c2                	mov    %eax,%edx
c01078e5:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c01078ea:	39 c2                	cmp    %eax,%edx
c01078ec:	72 1c                	jb     c010790a <pa2page+0x33>
        panic("pa2page called with invalid pa");
c01078ee:	c7 44 24 08 98 ba 10 	movl   $0xc010ba98,0x8(%esp)
c01078f5:	c0 
c01078f6:	c7 44 24 04 5f 00 00 	movl   $0x5f,0x4(%esp)
c01078fd:	00 
c01078fe:	c7 04 24 b7 ba 10 c0 	movl   $0xc010bab7,(%esp)
c0107905:	e8 3b 93 ff ff       	call   c0100c45 <__panic>
    return &pages[PPN(pa)];
c010790a:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c0107910:	8b 45 08             	mov    0x8(%ebp),%eax
c0107913:	c1 e8 0c             	shr    $0xc,%eax
c0107916:	c1 e0 05             	shl    $0x5,%eax
c0107919:	01 d0                	add    %edx,%eax
}
c010791b:	89 ec                	mov    %ebp,%esp
c010791d:	5d                   	pop    %ebp
c010791e:	c3                   	ret    

c010791f <pde2page>:
pde2page(pde_t pde) {
c010791f:	55                   	push   %ebp
c0107920:	89 e5                	mov    %esp,%ebp
c0107922:	83 ec 18             	sub    $0x18,%esp
    return pa2page(PDE_ADDR(pde));
c0107925:	8b 45 08             	mov    0x8(%ebp),%eax
c0107928:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c010792d:	89 04 24             	mov    %eax,(%esp)
c0107930:	e8 a2 ff ff ff       	call   c01078d7 <pa2page>
}
c0107935:	89 ec                	mov    %ebp,%esp
c0107937:	5d                   	pop    %ebp
c0107938:	c3                   	ret    

c0107939 <mm_create>:
 * 它包括内存映射列表、页目录、映射缓存等重要信息
 * 
 * @return 分配并初始化后的`mm_struct`结构体指针，如果分配失败则返回NULL
 */
struct mm_struct *
mm_create(void) {
c0107939:	55                   	push   %ebp
c010793a:	89 e5                	mov    %esp,%ebp
c010793c:	83 ec 28             	sub    $0x28,%esp
    // 分配一个mm_struct结构体的空间
    struct mm_struct *mm = kmalloc(sizeof(struct mm_struct));
c010793f:	c7 04 24 18 00 00 00 	movl   $0x18,(%esp)
c0107946:	e8 ff d1 ff ff       	call   c0104b4a <kmalloc>
c010794b:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 检查是否成功分配了内存
    if (mm != NULL) {
c010794e:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0107952:	74 59                	je     c01079ad <mm_create+0x74>
        // 初始化内存映射列表
        list_init(&(mm->mmap_list));
c0107954:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107957:	89 45 f0             	mov    %eax,-0x10(%ebp)
    elm->prev = elm->next = elm;
c010795a:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010795d:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0107960:	89 50 04             	mov    %edx,0x4(%eax)
c0107963:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107966:	8b 50 04             	mov    0x4(%eax),%edx
c0107969:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010796c:	89 10                	mov    %edx,(%eax)
}
c010796e:	90                   	nop
        // 设置映射缓存为NULL，表示尚未缓存任何映射
        mm->mmap_cache = NULL;
c010796f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107972:	c7 40 08 00 00 00 00 	movl   $0x0,0x8(%eax)
        // 设置页目录为NULL，表示尚未分配页目录
        mm->pgdir = NULL;
c0107979:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010797c:	c7 40 0c 00 00 00 00 	movl   $0x0,0xc(%eax)
        // 初始化映射计数为0，表示尚未创建任何内存映射
        mm->map_count = 0;
c0107983:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107986:	c7 40 10 00 00 00 00 	movl   $0x0,0x10(%eax)
        // 如果交换空间初始化成功，则为当前内存管理结构体进行交换空间初始化
        if (swap_init_ok) swap_init_mm(mm);
c010798d:	a1 a4 c0 12 c0       	mov    0xc012c0a4,%eax
c0107992:	85 c0                	test   %eax,%eax
c0107994:	74 0d                	je     c01079a3 <mm_create+0x6a>
c0107996:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107999:	89 04 24             	mov    %eax,(%esp)
c010799c:	e8 df ee ff ff       	call   c0106880 <swap_init_mm>
c01079a1:	eb 0a                	jmp    c01079ad <mm_create+0x74>
        else mm->sm_priv = NULL;
c01079a3:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01079a6:	c7 40 14 00 00 00 00 	movl   $0x0,0x14(%eax)
    }
    // 返回分配并初始化后的内存管理结构体指针
    return mm;
c01079ad:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01079b0:	89 ec                	mov    %ebp,%esp
c01079b2:	5d                   	pop    %ebp
c01079b3:	c3                   	ret    

c01079b4 <vma_create>:
 * @param vm_flags 虚拟内存区域的标志，表示内存区域的权限和特性。
 * 
 * @return 返回指向新创建的vma_struct结构体的指针，如果内存分配失败，则返回NULL。
 */
struct vma_struct *
vma_create(uintptr_t vm_start, uintptr_t vm_end, uint32_t vm_flags) {
c01079b4:	55                   	push   %ebp
c01079b5:	89 e5                	mov    %esp,%ebp
c01079b7:	83 ec 28             	sub    $0x28,%esp
    // 分配vma_struct结构体所需的内存空间
    struct vma_struct *vma = kmalloc(sizeof(struct vma_struct));
c01079ba:	c7 04 24 18 00 00 00 	movl   $0x18,(%esp)
c01079c1:	e8 84 d1 ff ff       	call   c0104b4a <kmalloc>
c01079c6:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 检查内存是否成功分配
    if (vma != NULL) {
c01079c9:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01079cd:	74 1b                	je     c01079ea <vma_create+0x36>
        // 初始化vma_struct的成员变量
        vma->vm_start = vm_start;
c01079cf:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01079d2:	8b 55 08             	mov    0x8(%ebp),%edx
c01079d5:	89 50 04             	mov    %edx,0x4(%eax)
        vma->vm_end = vm_end;
c01079d8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01079db:	8b 55 0c             	mov    0xc(%ebp),%edx
c01079de:	89 50 08             	mov    %edx,0x8(%eax)
        vma->vm_flags = vm_flags;
c01079e1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01079e4:	8b 55 10             	mov    0x10(%ebp),%edx
c01079e7:	89 50 0c             	mov    %edx,0xc(%eax)
    }
    // 返回指向新创建的vma_struct结构体的指针，或在内存分配失败时返回NULL
    return vma;
c01079ea:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01079ed:	89 ec                	mov    %ebp,%esp
c01079ef:	5d                   	pop    %ebp
c01079f0:	c3                   	ret    

c01079f1 <find_vma>:
 * 此函数首先检查mmap_cache是否包含所需的VMA，以加速查找过程
 * 如果mmap_cache未命中，则遍历VMA列表，直到找到包含给定地址的VMA或确定不存在这样的VMA
 * 如果找到了合适的VMA，它将更新mmap_cache以供后续查找使用
 */
struct vma_struct *
find_vma(struct mm_struct *mm, uintptr_t addr) {
c01079f1:	55                   	push   %ebp
c01079f2:	89 e5                	mov    %esp,%ebp
c01079f4:	83 ec 20             	sub    $0x20,%esp
    struct vma_struct *vma = NULL;// 初始化VMA指针为NULL
c01079f7:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    if (mm != NULL) {// 检查传入的内存描述符是否有效
c01079fe:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0107a02:	0f 84 95 00 00 00    	je     c0107a9d <find_vma+0xac>
        // 检查mmap_cache是否包含所需的VMA
        vma = mm->mmap_cache;
c0107a08:	8b 45 08             	mov    0x8(%ebp),%eax
c0107a0b:	8b 40 08             	mov    0x8(%eax),%eax
c0107a0e:	89 45 fc             	mov    %eax,-0x4(%ebp)
        if (!(vma != NULL && vma->vm_start <= addr && vma->vm_end > addr)) {
c0107a11:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c0107a15:	74 16                	je     c0107a2d <find_vma+0x3c>
c0107a17:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0107a1a:	8b 40 04             	mov    0x4(%eax),%eax
c0107a1d:	39 45 0c             	cmp    %eax,0xc(%ebp)
c0107a20:	72 0b                	jb     c0107a2d <find_vma+0x3c>
c0107a22:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0107a25:	8b 40 08             	mov    0x8(%eax),%eax
c0107a28:	39 45 0c             	cmp    %eax,0xc(%ebp)
c0107a2b:	72 61                	jb     c0107a8e <find_vma+0x9d>
                // 如果mmap_cache未命中，则开始遍历VMA列表
                bool found = 0;// 初始化找到标志为0
c0107a2d:	c7 45 f8 00 00 00 00 	movl   $0x0,-0x8(%ebp)
                // 获取VMA列表的头指针
                list_entry_t *list = &(mm->mmap_list), *le = list;
c0107a34:	8b 45 08             	mov    0x8(%ebp),%eax
c0107a37:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0107a3a:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107a3d:	89 45 f4             	mov    %eax,-0xc(%ebp)
                while ((le = list_next(le)) != list) { // 遍历VMA列表
c0107a40:	eb 28                	jmp    c0107a6a <find_vma+0x79>
                    vma = le2vma(le, list_link);// 将链表项转换为VMA结构
c0107a42:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107a45:	83 e8 10             	sub    $0x10,%eax
c0107a48:	89 45 fc             	mov    %eax,-0x4(%ebp)
                    // 检查当前VMA是否包含给定地址
                    if (vma->vm_start<=addr && addr < vma->vm_end) {
c0107a4b:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0107a4e:	8b 40 04             	mov    0x4(%eax),%eax
c0107a51:	39 45 0c             	cmp    %eax,0xc(%ebp)
c0107a54:	72 14                	jb     c0107a6a <find_vma+0x79>
c0107a56:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0107a59:	8b 40 08             	mov    0x8(%eax),%eax
c0107a5c:	39 45 0c             	cmp    %eax,0xc(%ebp)
c0107a5f:	73 09                	jae    c0107a6a <find_vma+0x79>
                        found = 1;// 找到合适的VMA
c0107a61:	c7 45 f8 01 00 00 00 	movl   $0x1,-0x8(%ebp)
                        break;// 结束循环
c0107a68:	eb 17                	jmp    c0107a81 <find_vma+0x90>
c0107a6a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107a6d:	89 45 ec             	mov    %eax,-0x14(%ebp)
    return listelm->next;
c0107a70:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107a73:	8b 40 04             	mov    0x4(%eax),%eax
                while ((le = list_next(le)) != list) { // 遍历VMA列表
c0107a76:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0107a79:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107a7c:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c0107a7f:	75 c1                	jne    c0107a42 <find_vma+0x51>
                    }
                }
                if (!found) {// 如果未找到合适的VMA
c0107a81:	83 7d f8 00          	cmpl   $0x0,-0x8(%ebp)
c0107a85:	75 07                	jne    c0107a8e <find_vma+0x9d>
                    vma = NULL;// 将VMA指针设置为NULL
c0107a87:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
                }
        }
        // 如果找到了合适的VMA，更新mmap_cache
        if (vma != NULL) {
c0107a8e:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c0107a92:	74 09                	je     c0107a9d <find_vma+0xac>
            mm->mmap_cache = vma;// 更新mmap_cache以加速后续查找
c0107a94:	8b 45 08             	mov    0x8(%ebp),%eax
c0107a97:	8b 55 fc             	mov    -0x4(%ebp),%edx
c0107a9a:	89 50 08             	mov    %edx,0x8(%eax)
        }
    }
    return vma;
c0107a9d:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c0107aa0:	89 ec                	mov    %ebp,%esp
c0107aa2:	5d                   	pop    %ebp
c0107aa3:	c3                   	ret    

c0107aa4 <check_vma_overlap>:
 * 
 * @param prev 指向前一个虚拟内存区域（VMA）的结构体指针
 * @param next 指向后一个虚拟内存区域（VMA）的结构体指针
 */
static inline void
check_vma_overlap(struct vma_struct *prev, struct vma_struct *next) {
c0107aa4:	55                   	push   %ebp
c0107aa5:	89 e5                	mov    %esp,%ebp
c0107aa7:	83 ec 18             	sub    $0x18,%esp
    assert(prev->vm_start < prev->vm_end);// 确保前一个VMA的地址范围是有效的
c0107aaa:	8b 45 08             	mov    0x8(%ebp),%eax
c0107aad:	8b 50 04             	mov    0x4(%eax),%edx
c0107ab0:	8b 45 08             	mov    0x8(%ebp),%eax
c0107ab3:	8b 40 08             	mov    0x8(%eax),%eax
c0107ab6:	39 c2                	cmp    %eax,%edx
c0107ab8:	72 24                	jb     c0107ade <check_vma_overlap+0x3a>
c0107aba:	c7 44 24 0c c5 ba 10 	movl   $0xc010bac5,0xc(%esp)
c0107ac1:	c0 
c0107ac2:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107ac9:	c0 
c0107aca:	c7 44 24 04 a1 00 00 	movl   $0xa1,0x4(%esp)
c0107ad1:	00 
c0107ad2:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107ad9:	e8 67 91 ff ff       	call   c0100c45 <__panic>
    assert(prev->vm_end <= next->vm_start);// 确保两个VMA之间没有重叠
c0107ade:	8b 45 08             	mov    0x8(%ebp),%eax
c0107ae1:	8b 50 08             	mov    0x8(%eax),%edx
c0107ae4:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107ae7:	8b 40 04             	mov    0x4(%eax),%eax
c0107aea:	39 c2                	cmp    %eax,%edx
c0107aec:	76 24                	jbe    c0107b12 <check_vma_overlap+0x6e>
c0107aee:	c7 44 24 0c 08 bb 10 	movl   $0xc010bb08,0xc(%esp)
c0107af5:	c0 
c0107af6:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107afd:	c0 
c0107afe:	c7 44 24 04 a2 00 00 	movl   $0xa2,0x4(%esp)
c0107b05:	00 
c0107b06:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107b0d:	e8 33 91 ff ff       	call   c0100c45 <__panic>
    assert(next->vm_start < next->vm_end);// 确保后一个VMA的地址范围是有效的
c0107b12:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107b15:	8b 50 04             	mov    0x4(%eax),%edx
c0107b18:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107b1b:	8b 40 08             	mov    0x8(%eax),%eax
c0107b1e:	39 c2                	cmp    %eax,%edx
c0107b20:	72 24                	jb     c0107b46 <check_vma_overlap+0xa2>
c0107b22:	c7 44 24 0c 27 bb 10 	movl   $0xc010bb27,0xc(%esp)
c0107b29:	c0 
c0107b2a:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107b31:	c0 
c0107b32:	c7 44 24 04 a3 00 00 	movl   $0xa3,0x4(%esp)
c0107b39:	00 
c0107b3a:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107b41:	e8 ff 90 ff ff       	call   c0100c45 <__panic>
}
c0107b46:	90                   	nop
c0107b47:	89 ec                	mov    %ebp,%esp
c0107b49:	5d                   	pop    %ebp
c0107b4a:	c3                   	ret    

c0107b4b <insert_vma_struct>:
 *
 * @param mm 指向内存描述符结构 `struct mm_struct` 的指针，表示一个进程的内存空间。
 * @param vma 指向要插入的VMA结构 `struct vma_struct` 的指针，描述一个内存区域。
 */
void
insert_vma_struct(struct mm_struct *mm, struct vma_struct *vma) {
c0107b4b:	55                   	push   %ebp
c0107b4c:	89 e5                	mov    %esp,%ebp
c0107b4e:	83 ec 48             	sub    $0x48,%esp
    // 断言VMA结构的起始地址小于结束地址，确保VMA结构的有效性。
    assert(vma->vm_start < vma->vm_end);
c0107b51:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107b54:	8b 50 04             	mov    0x4(%eax),%edx
c0107b57:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107b5a:	8b 40 08             	mov    0x8(%eax),%eax
c0107b5d:	39 c2                	cmp    %eax,%edx
c0107b5f:	72 24                	jb     c0107b85 <insert_vma_struct+0x3a>
c0107b61:	c7 44 24 0c 45 bb 10 	movl   $0xc010bb45,0xc(%esp)
c0107b68:	c0 
c0107b69:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107b70:	c0 
c0107b71:	c7 44 24 04 b4 00 00 	movl   $0xb4,0x4(%esp)
c0107b78:	00 
c0107b79:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107b80:	e8 c0 90 ff ff       	call   c0100c45 <__panic>
    // 指向内存描述符中的VMA链表。
    list_entry_t *list = &(mm->mmap_list);
c0107b85:	8b 45 08             	mov    0x8(%ebp),%eax
c0107b88:	89 45 ec             	mov    %eax,-0x14(%ebp)
     // 遍历链表以找到新VMA结构的正确插入位置。
    list_entry_t *le_prev = list, *le_next;
c0107b8b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107b8e:	89 45 f4             	mov    %eax,-0xc(%ebp)

        list_entry_t *le = list;
c0107b91:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107b94:	89 45 f0             	mov    %eax,-0x10(%ebp)
        // 遍历链表以找到新VMA结构的正确插入位置
        while ((le = list_next(le)) != list) {
c0107b97:	eb 1f                	jmp    c0107bb8 <insert_vma_struct+0x6d>
            struct vma_struct *mmap_prev = le2vma(le, list_link);
c0107b99:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107b9c:	83 e8 10             	sub    $0x10,%eax
c0107b9f:	89 45 e8             	mov    %eax,-0x18(%ebp)
            // 如果当前VMA的起始地址大于新VMA的起始地址，则跳出循环
            if (mmap_prev->vm_start > vma->vm_start) {
c0107ba2:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107ba5:	8b 50 04             	mov    0x4(%eax),%edx
c0107ba8:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107bab:	8b 40 04             	mov    0x4(%eax),%eax
c0107bae:	39 c2                	cmp    %eax,%edx
c0107bb0:	77 1f                	ja     c0107bd1 <insert_vma_struct+0x86>
                break;
            }
            le_prev = le;
c0107bb2:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107bb5:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0107bb8:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107bbb:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0107bbe:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0107bc1:	8b 40 04             	mov    0x4(%eax),%eax
        while ((le = list_next(le)) != list) {
c0107bc4:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0107bc7:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107bca:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0107bcd:	75 ca                	jne    c0107b99 <insert_vma_struct+0x4e>
c0107bcf:	eb 01                	jmp    c0107bd2 <insert_vma_struct+0x87>
                break;
c0107bd1:	90                   	nop
c0107bd2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107bd5:	89 45 dc             	mov    %eax,-0x24(%ebp)
c0107bd8:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0107bdb:	8b 40 04             	mov    0x4(%eax),%eax
        }
    // 获取下一个链表项
    le_next = list_next(le_prev);
c0107bde:	89 45 e4             	mov    %eax,-0x1c(%ebp)

    /* check overlap */
    // 检查前一个VMA结构是否与新VMA结构重叠
    if (le_prev != list) {
c0107be1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107be4:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0107be7:	74 15                	je     c0107bfe <insert_vma_struct+0xb3>
        check_vma_overlap(le2vma(le_prev, list_link), vma);
c0107be9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107bec:	8d 50 f0             	lea    -0x10(%eax),%edx
c0107bef:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107bf2:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107bf6:	89 14 24             	mov    %edx,(%esp)
c0107bf9:	e8 a6 fe ff ff       	call   c0107aa4 <check_vma_overlap>
    }
    // 检查下一个VMA结构是否与新VMA结构重叠
    if (le_next != list) {
c0107bfe:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107c01:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0107c04:	74 15                	je     c0107c1b <insert_vma_struct+0xd0>
        check_vma_overlap(vma, le2vma(le_next, list_link));
c0107c06:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107c09:	83 e8 10             	sub    $0x10,%eax
c0107c0c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107c10:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107c13:	89 04 24             	mov    %eax,(%esp)
c0107c16:	e8 89 fe ff ff       	call   c0107aa4 <check_vma_overlap>
    }
    // 设置VMA结构所属的内存描述符
    vma->vm_mm = mm;
c0107c1b:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107c1e:	8b 55 08             	mov    0x8(%ebp),%edx
c0107c21:	89 10                	mov    %edx,(%eax)
    // 将新VMA结构插入链表
    list_add_after(le_prev, &(vma->list_link));
c0107c23:	8b 45 0c             	mov    0xc(%ebp),%eax
c0107c26:	8d 50 10             	lea    0x10(%eax),%edx
c0107c29:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107c2c:	89 45 d8             	mov    %eax,-0x28(%ebp)
c0107c2f:	89 55 d4             	mov    %edx,-0x2c(%ebp)
    __list_add(elm, listelm, listelm->next);
c0107c32:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0107c35:	8b 40 04             	mov    0x4(%eax),%eax
c0107c38:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0107c3b:	89 55 d0             	mov    %edx,-0x30(%ebp)
c0107c3e:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0107c41:	89 55 cc             	mov    %edx,-0x34(%ebp)
c0107c44:	89 45 c8             	mov    %eax,-0x38(%ebp)
    prev->next = next->prev = elm;
c0107c47:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0107c4a:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0107c4d:	89 10                	mov    %edx,(%eax)
c0107c4f:	8b 45 c8             	mov    -0x38(%ebp),%eax
c0107c52:	8b 10                	mov    (%eax),%edx
c0107c54:	8b 45 cc             	mov    -0x34(%ebp),%eax
c0107c57:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c0107c5a:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0107c5d:	8b 55 c8             	mov    -0x38(%ebp),%edx
c0107c60:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0107c63:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0107c66:	8b 55 cc             	mov    -0x34(%ebp),%edx
c0107c69:	89 10                	mov    %edx,(%eax)
}
c0107c6b:	90                   	nop
}
c0107c6c:	90                   	nop
    // 增加内存描述符中的映射计数
    mm->map_count ++;
c0107c6d:	8b 45 08             	mov    0x8(%ebp),%eax
c0107c70:	8b 40 10             	mov    0x10(%eax),%eax
c0107c73:	8d 50 01             	lea    0x1(%eax),%edx
c0107c76:	8b 45 08             	mov    0x8(%ebp),%eax
c0107c79:	89 50 10             	mov    %edx,0x10(%eax)
}
c0107c7c:	90                   	nop
c0107c7d:	89 ec                	mov    %ebp,%esp
c0107c7f:	5d                   	pop    %ebp
c0107c80:	c3                   	ret    

c0107c81 <mm_destroy>:
 * 此函数遍历并销毁与内存管理结构（mm_struct）关联的所有虚拟内存区域（VMA），
 * 然后释放内存管理结构本身所占用的内存。这样做是为了确保在销毁内存管理结构之前，
 * 所有相关的资源都被正确地释放。
 */
void
mm_destroy(struct mm_struct *mm) {
c0107c81:	55                   	push   %ebp
c0107c82:	89 e5                	mov    %esp,%ebp
c0107c84:	83 ec 38             	sub    $0x38,%esp
    // 获取内存映射列表的头指针
    list_entry_t *list = &(mm->mmap_list), *le;
c0107c87:	8b 45 08             	mov    0x8(%ebp),%eax
c0107c8a:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 遍历内存映射列表，直到回到起点
    while ((le = list_next(list)) != list) {
c0107c8d:	eb 38                	jmp    c0107cc7 <mm_destroy+0x46>
c0107c8f:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107c92:	89 45 ec             	mov    %eax,-0x14(%ebp)
    __list_del(listelm->prev, listelm->next);
c0107c95:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0107c98:	8b 40 04             	mov    0x4(%eax),%eax
c0107c9b:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0107c9e:	8b 12                	mov    (%edx),%edx
c0107ca0:	89 55 e8             	mov    %edx,-0x18(%ebp)
c0107ca3:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    prev->next = next;
c0107ca6:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107ca9:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0107cac:	89 50 04             	mov    %edx,0x4(%eax)
    next->prev = prev;
c0107caf:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107cb2:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0107cb5:	89 10                	mov    %edx,(%eax)
}
c0107cb7:	90                   	nop
}
c0107cb8:	90                   	nop
        // 从列表中删除当前虚拟内存区域的项
        list_del(le);
        // 释放虚拟内存区域结构的内存
        kfree(le2vma(le, list_link));
c0107cb9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107cbc:	83 e8 10             	sub    $0x10,%eax
c0107cbf:	89 04 24             	mov    %eax,(%esp)
c0107cc2:	e8 a0 ce ff ff       	call   c0104b67 <kfree>
c0107cc7:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107cca:	89 45 e0             	mov    %eax,-0x20(%ebp)
    return listelm->next;
c0107ccd:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0107cd0:	8b 40 04             	mov    0x4(%eax),%eax
    while ((le = list_next(list)) != list) {
c0107cd3:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0107cd6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107cd9:	3b 45 f4             	cmp    -0xc(%ebp),%eax
c0107cdc:	75 b1                	jne    c0107c8f <mm_destroy+0xe>
        //kfree(le2vma(le, list_link), sizeof(struct vma_struct));  //kfree vma        
    }
    // 释放内存管理结构本身的内存
    kfree(mm); //kfree mm
c0107cde:	8b 45 08             	mov    0x8(%ebp),%eax
c0107ce1:	89 04 24             	mov    %eax,(%esp)
c0107ce4:	e8 7e ce ff ff       	call   c0104b67 <kfree>
    //kfree(mm, sizeof(struct mm_struct)); //kfree mm
    // 将指针设置为NULL，表示该结构已被销毁
    mm=NULL;
c0107ce9:	c7 45 08 00 00 00 00 	movl   $0x0,0x8(%ebp)
}
c0107cf0:	90                   	nop
c0107cf1:	89 ec                	mov    %ebp,%esp
c0107cf3:	5d                   	pop    %ebp
c0107cf4:	c3                   	ret    

c0107cf5 <vmm_init>:
/**
 * 初始化虚拟内存管理(VMM)系统。
 * 此函数通过执行一系列检查来确保VMM系统可以正确初始化和运行。
 */
void
vmm_init(void) {
c0107cf5:	55                   	push   %ebp
c0107cf6:	89 e5                	mov    %esp,%ebp
c0107cf8:	83 ec 08             	sub    $0x8,%esp
    // 检查VMM系统的状态和环境，以确保其能够正常工作。
    check_vmm();
c0107cfb:	e8 05 00 00 00       	call   c0107d05 <check_vmm>
}
c0107d00:	90                   	nop
c0107d01:	89 ec                	mov    %ebp,%esp
c0107d03:	5d                   	pop    %ebp
c0107d04:	c3                   	ret    

c0107d05 <check_vmm>:
 * 此函数的目的是确保虚拟内存管理系统的正确性通过检查内存区域结构（VMA）、页面故障处理以及免费页面计数的 consistency 来实现
 * 它首先保存当前的免费页面数量，然后执行与 VMA 和页面故障相关的检查，最后确认免费页面数量未发生变化
 * 这是为了确保在检查过程中，内存状态没有因为错误或意外的修改而改变，从而验证内存管理的正确性
 */
static void
check_vmm(void) {
c0107d05:	55                   	push   %ebp
c0107d06:	89 e5                	mov    %esp,%ebp
c0107d08:	83 ec 28             	sub    $0x28,%esp
    // 保存当前的免费页面数量，用于后续的 consistency 检查
    size_t nr_free_pages_store = nr_free_pages();
c0107d0b:	e8 6d d3 ff ff       	call   c010507d <nr_free_pages>
c0107d10:	89 45 f4             	mov    %eax,-0xc(%ebp)
    // 检查虚拟内存区域（VMA）结构的正确性
    check_vma_struct();
c0107d13:	e8 16 00 00 00       	call   c0107d2e <check_vma_struct>
    // 检查页面故障处理的正确性
    check_pgfault();
c0107d18:	e8 a5 04 00 00       	call   c01081c2 <check_pgfault>
    // 确保在检查过程中免费页面数量未发生变化，表明内存管理操作是正确的
    // assert(nr_free_pages_store == nr_free_pages());
    // 如果所有检查都通过，输出成功信息
    cprintf("check_vmm() succeeded.\n");
c0107d1d:	c7 04 24 61 bb 10 c0 	movl   $0xc010bb61,(%esp)
c0107d24:	e8 4f 86 ff ff       	call   c0100378 <cprintf>
}
c0107d29:	90                   	nop
c0107d2a:	89 ec                	mov    %ebp,%esp
c0107d2c:	5d                   	pop    %ebp
c0107d2d:	c3                   	ret    

c0107d2e <check_vma_struct>:

//测试虚拟内存区域（VMA）结构的创建、插入和查找功能。
static void
check_vma_struct(void) {
c0107d2e:	55                   	push   %ebp
c0107d2f:	89 e5                	mov    %esp,%ebp
c0107d31:	83 ec 68             	sub    $0x68,%esp
    // 记录当前空闲页面数量
    size_t nr_free_pages_store = nr_free_pages();
c0107d34:	e8 44 d3 ff ff       	call   c010507d <nr_free_pages>
c0107d39:	89 45 ec             	mov    %eax,-0x14(%ebp)

    struct mm_struct *mm = mm_create();// 创建内存管理结构 mm
c0107d3c:	e8 f8 fb ff ff       	call   c0107939 <mm_create>
c0107d41:	89 45 e8             	mov    %eax,-0x18(%ebp)
    assert(mm != NULL);// 确保 mm 不为 NULL
c0107d44:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0107d48:	75 24                	jne    c0107d6e <check_vma_struct+0x40>
c0107d4a:	c7 44 24 0c 79 bb 10 	movl   $0xc010bb79,0xc(%esp)
c0107d51:	c0 
c0107d52:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107d59:	c0 
c0107d5a:	c7 44 24 04 1d 01 00 	movl   $0x11d,0x4(%esp)
c0107d61:	00 
c0107d62:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107d69:	e8 d7 8e ff ff       	call   c0100c45 <__panic>

    int step1 = 10, step2 = step1 * 10;// 定义两个步骤的步数
c0107d6e:	c7 45 e4 0a 00 00 00 	movl   $0xa,-0x1c(%ebp)
c0107d75:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0107d78:	89 d0                	mov    %edx,%eax
c0107d7a:	c1 e0 02             	shl    $0x2,%eax
c0107d7d:	01 d0                	add    %edx,%eax
c0107d7f:	01 c0                	add    %eax,%eax
c0107d81:	89 45 e0             	mov    %eax,-0x20(%ebp)

    int i;
    for (i = step1; i >= 1; i --) {// 第一步：创建并插入10个VMA
c0107d84:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107d87:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0107d8a:	eb 6f                	jmp    c0107dfb <check_vma_struct+0xcd>
        // 创建 VMA 结构
        struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0);
c0107d8c:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0107d8f:	89 d0                	mov    %edx,%eax
c0107d91:	c1 e0 02             	shl    $0x2,%eax
c0107d94:	01 d0                	add    %edx,%eax
c0107d96:	83 c0 02             	add    $0x2,%eax
c0107d99:	89 c1                	mov    %eax,%ecx
c0107d9b:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0107d9e:	89 d0                	mov    %edx,%eax
c0107da0:	c1 e0 02             	shl    $0x2,%eax
c0107da3:	01 d0                	add    %edx,%eax
c0107da5:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0107dac:	00 
c0107dad:	89 4c 24 04          	mov    %ecx,0x4(%esp)
c0107db1:	89 04 24             	mov    %eax,(%esp)
c0107db4:	e8 fb fb ff ff       	call   c01079b4 <vma_create>
c0107db9:	89 45 bc             	mov    %eax,-0x44(%ebp)
        assert(vma != NULL);// 确保 VMA 不为 NULL
c0107dbc:	83 7d bc 00          	cmpl   $0x0,-0x44(%ebp)
c0107dc0:	75 24                	jne    c0107de6 <check_vma_struct+0xb8>
c0107dc2:	c7 44 24 0c 84 bb 10 	movl   $0xc010bb84,0xc(%esp)
c0107dc9:	c0 
c0107dca:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107dd1:	c0 
c0107dd2:	c7 44 24 04 25 01 00 	movl   $0x125,0x4(%esp)
c0107dd9:	00 
c0107dda:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107de1:	e8 5f 8e ff ff       	call   c0100c45 <__panic>
        insert_vma_struct(mm, vma); //将 VMA 插入到 mm 中
c0107de6:	8b 45 bc             	mov    -0x44(%ebp),%eax
c0107de9:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107ded:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107df0:	89 04 24             	mov    %eax,(%esp)
c0107df3:	e8 53 fd ff ff       	call   c0107b4b <insert_vma_struct>
    for (i = step1; i >= 1; i --) {// 第一步：创建并插入10个VMA
c0107df8:	ff 4d f4             	decl   -0xc(%ebp)
c0107dfb:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0107dff:	7f 8b                	jg     c0107d8c <check_vma_struct+0x5e>
    }

    for (i = step1 + 1; i <= step2; i ++) {// 第二步：创建并插入90个VMA
c0107e01:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0107e04:	40                   	inc    %eax
c0107e05:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0107e08:	eb 6f                	jmp    c0107e79 <check_vma_struct+0x14b>
        // 创建 VMA 结构
        struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0);
c0107e0a:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0107e0d:	89 d0                	mov    %edx,%eax
c0107e0f:	c1 e0 02             	shl    $0x2,%eax
c0107e12:	01 d0                	add    %edx,%eax
c0107e14:	83 c0 02             	add    $0x2,%eax
c0107e17:	89 c1                	mov    %eax,%ecx
c0107e19:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0107e1c:	89 d0                	mov    %edx,%eax
c0107e1e:	c1 e0 02             	shl    $0x2,%eax
c0107e21:	01 d0                	add    %edx,%eax
c0107e23:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c0107e2a:	00 
c0107e2b:	89 4c 24 04          	mov    %ecx,0x4(%esp)
c0107e2f:	89 04 24             	mov    %eax,(%esp)
c0107e32:	e8 7d fb ff ff       	call   c01079b4 <vma_create>
c0107e37:	89 45 c0             	mov    %eax,-0x40(%ebp)
        assert(vma != NULL);// 确保 VMA 不为 NULL
c0107e3a:	83 7d c0 00          	cmpl   $0x0,-0x40(%ebp)
c0107e3e:	75 24                	jne    c0107e64 <check_vma_struct+0x136>
c0107e40:	c7 44 24 0c 84 bb 10 	movl   $0xc010bb84,0xc(%esp)
c0107e47:	c0 
c0107e48:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107e4f:	c0 
c0107e50:	c7 44 24 04 2c 01 00 	movl   $0x12c,0x4(%esp)
c0107e57:	00 
c0107e58:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107e5f:	e8 e1 8d ff ff       	call   c0100c45 <__panic>
        insert_vma_struct(mm, vma);// 将 VMA 插入到 mm 中
c0107e64:	8b 45 c0             	mov    -0x40(%ebp),%eax
c0107e67:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107e6b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107e6e:	89 04 24             	mov    %eax,(%esp)
c0107e71:	e8 d5 fc ff ff       	call   c0107b4b <insert_vma_struct>
    for (i = step1 + 1; i <= step2; i ++) {// 第二步：创建并插入90个VMA
c0107e76:	ff 45 f4             	incl   -0xc(%ebp)
c0107e79:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107e7c:	3b 45 e0             	cmp    -0x20(%ebp),%eax
c0107e7f:	7e 89                	jle    c0107e0a <check_vma_struct+0xdc>
    }
    // 获取 VMA 链表的第一个节点
    list_entry_t *le = list_next(&(mm->mmap_list));
c0107e81:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107e84:	89 45 b8             	mov    %eax,-0x48(%ebp)
c0107e87:	8b 45 b8             	mov    -0x48(%ebp),%eax
c0107e8a:	8b 40 04             	mov    0x4(%eax),%eax
c0107e8d:	89 45 f0             	mov    %eax,-0x10(%ebp)

    for (i = 1; i <= step2; i ++) {// 验证插入顺序
c0107e90:	c7 45 f4 01 00 00 00 	movl   $0x1,-0xc(%ebp)
c0107e97:	e9 96 00 00 00       	jmp    c0107f32 <check_vma_struct+0x204>
        assert(le != &(mm->mmap_list));// 确保节点不为空
c0107e9c:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107e9f:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c0107ea2:	75 24                	jne    c0107ec8 <check_vma_struct+0x19a>
c0107ea4:	c7 44 24 0c 90 bb 10 	movl   $0xc010bb90,0xc(%esp)
c0107eab:	c0 
c0107eac:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107eb3:	c0 
c0107eb4:	c7 44 24 04 33 01 00 	movl   $0x133,0x4(%esp)
c0107ebb:	00 
c0107ebc:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107ec3:	e8 7d 8d ff ff       	call   c0100c45 <__panic>
        struct vma_struct *mmap = le2vma(le, list_link);// 将链表节点转换为 VMA 结构
c0107ec8:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107ecb:	83 e8 10             	sub    $0x10,%eax
c0107ece:	89 45 c4             	mov    %eax,-0x3c(%ebp)
        // 确认 VMA 的起始和结束地址
        assert(mmap->vm_start == i * 5 && mmap->vm_end == i * 5 + 2);
c0107ed1:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0107ed4:	8b 48 04             	mov    0x4(%eax),%ecx
c0107ed7:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0107eda:	89 d0                	mov    %edx,%eax
c0107edc:	c1 e0 02             	shl    $0x2,%eax
c0107edf:	01 d0                	add    %edx,%eax
c0107ee1:	39 c1                	cmp    %eax,%ecx
c0107ee3:	75 17                	jne    c0107efc <check_vma_struct+0x1ce>
c0107ee5:	8b 45 c4             	mov    -0x3c(%ebp),%eax
c0107ee8:	8b 48 08             	mov    0x8(%eax),%ecx
c0107eeb:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0107eee:	89 d0                	mov    %edx,%eax
c0107ef0:	c1 e0 02             	shl    $0x2,%eax
c0107ef3:	01 d0                	add    %edx,%eax
c0107ef5:	83 c0 02             	add    $0x2,%eax
c0107ef8:	39 c1                	cmp    %eax,%ecx
c0107efa:	74 24                	je     c0107f20 <check_vma_struct+0x1f2>
c0107efc:	c7 44 24 0c a8 bb 10 	movl   $0xc010bba8,0xc(%esp)
c0107f03:	c0 
c0107f04:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107f0b:	c0 
c0107f0c:	c7 44 24 04 36 01 00 	movl   $0x136,0x4(%esp)
c0107f13:	00 
c0107f14:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107f1b:	e8 25 8d ff ff       	call   c0100c45 <__panic>
c0107f20:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0107f23:	89 45 b4             	mov    %eax,-0x4c(%ebp)
c0107f26:	8b 45 b4             	mov    -0x4c(%ebp),%eax
c0107f29:	8b 40 04             	mov    0x4(%eax),%eax
        le = list_next(le);// 移动到下一个节点
c0107f2c:	89 45 f0             	mov    %eax,-0x10(%ebp)
    for (i = 1; i <= step2; i ++) {// 验证插入顺序
c0107f2f:	ff 45 f4             	incl   -0xc(%ebp)
c0107f32:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107f35:	3b 45 e0             	cmp    -0x20(%ebp),%eax
c0107f38:	0f 8e 5e ff ff ff    	jle    c0107e9c <check_vma_struct+0x16e>
    }

    for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA
c0107f3e:	c7 45 f4 05 00 00 00 	movl   $0x5,-0xc(%ebp)
c0107f45:	e9 cb 01 00 00       	jmp    c0108115 <check_vma_struct+0x3e7>
        struct vma_struct *vma1 = find_vma(mm, i);// 查找地址 i 处的 VMA
c0107f4a:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107f4d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107f51:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107f54:	89 04 24             	mov    %eax,(%esp)
c0107f57:	e8 95 fa ff ff       	call   c01079f1 <find_vma>
c0107f5c:	89 45 d8             	mov    %eax,-0x28(%ebp)
        assert(vma1 != NULL);// 确保找到 VMA
c0107f5f:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
c0107f63:	75 24                	jne    c0107f89 <check_vma_struct+0x25b>
c0107f65:	c7 44 24 0c dd bb 10 	movl   $0xc010bbdd,0xc(%esp)
c0107f6c:	c0 
c0107f6d:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107f74:	c0 
c0107f75:	c7 44 24 04 3c 01 00 	movl   $0x13c,0x4(%esp)
c0107f7c:	00 
c0107f7d:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107f84:	e8 bc 8c ff ff       	call   c0100c45 <__panic>
        // 查找地址 i + 1 处的 VMA
        struct vma_struct *vma2 = find_vma(mm, i+1);
c0107f89:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107f8c:	40                   	inc    %eax
c0107f8d:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107f91:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107f94:	89 04 24             	mov    %eax,(%esp)
c0107f97:	e8 55 fa ff ff       	call   c01079f1 <find_vma>
c0107f9c:	89 45 d4             	mov    %eax,-0x2c(%ebp)
        assert(vma2 != NULL);// 确保找到 VMA
c0107f9f:	83 7d d4 00          	cmpl   $0x0,-0x2c(%ebp)
c0107fa3:	75 24                	jne    c0107fc9 <check_vma_struct+0x29b>
c0107fa5:	c7 44 24 0c ea bb 10 	movl   $0xc010bbea,0xc(%esp)
c0107fac:	c0 
c0107fad:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107fb4:	c0 
c0107fb5:	c7 44 24 04 3f 01 00 	movl   $0x13f,0x4(%esp)
c0107fbc:	00 
c0107fbd:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0107fc4:	e8 7c 8c ff ff       	call   c0100c45 <__panic>
        // 查找地址 i + 2 处的 VMA
        struct vma_struct *vma3 = find_vma(mm, i+2);
c0107fc9:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0107fcc:	83 c0 02             	add    $0x2,%eax
c0107fcf:	89 44 24 04          	mov    %eax,0x4(%esp)
c0107fd3:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0107fd6:	89 04 24             	mov    %eax,(%esp)
c0107fd9:	e8 13 fa ff ff       	call   c01079f1 <find_vma>
c0107fde:	89 45 d0             	mov    %eax,-0x30(%ebp)
        assert(vma3 == NULL);// 确保未找到 VMA
c0107fe1:	83 7d d0 00          	cmpl   $0x0,-0x30(%ebp)
c0107fe5:	74 24                	je     c010800b <check_vma_struct+0x2dd>
c0107fe7:	c7 44 24 0c f7 bb 10 	movl   $0xc010bbf7,0xc(%esp)
c0107fee:	c0 
c0107fef:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0107ff6:	c0 
c0107ff7:	c7 44 24 04 42 01 00 	movl   $0x142,0x4(%esp)
c0107ffe:	00 
c0107fff:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0108006:	e8 3a 8c ff ff       	call   c0100c45 <__panic>
        // 查找地址 i + 3 处的 VMA
        struct vma_struct *vma4 = find_vma(mm, i+3);
c010800b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010800e:	83 c0 03             	add    $0x3,%eax
c0108011:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108015:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108018:	89 04 24             	mov    %eax,(%esp)
c010801b:	e8 d1 f9 ff ff       	call   c01079f1 <find_vma>
c0108020:	89 45 cc             	mov    %eax,-0x34(%ebp)
        assert(vma4 == NULL);// 确保未找到 VMA
c0108023:	83 7d cc 00          	cmpl   $0x0,-0x34(%ebp)
c0108027:	74 24                	je     c010804d <check_vma_struct+0x31f>
c0108029:	c7 44 24 0c 04 bc 10 	movl   $0xc010bc04,0xc(%esp)
c0108030:	c0 
c0108031:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0108038:	c0 
c0108039:	c7 44 24 04 45 01 00 	movl   $0x145,0x4(%esp)
c0108040:	00 
c0108041:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0108048:	e8 f8 8b ff ff       	call   c0100c45 <__panic>
        // 查找地址 i + 4 处的 VMA
        struct vma_struct *vma5 = find_vma(mm, i+4);
c010804d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108050:	83 c0 04             	add    $0x4,%eax
c0108053:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108057:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010805a:	89 04 24             	mov    %eax,(%esp)
c010805d:	e8 8f f9 ff ff       	call   c01079f1 <find_vma>
c0108062:	89 45 c8             	mov    %eax,-0x38(%ebp)
        assert(vma5 == NULL);// 确保未找到 VMA
c0108065:	83 7d c8 00          	cmpl   $0x0,-0x38(%ebp)
c0108069:	74 24                	je     c010808f <check_vma_struct+0x361>
c010806b:	c7 44 24 0c 11 bc 10 	movl   $0xc010bc11,0xc(%esp)
c0108072:	c0 
c0108073:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c010807a:	c0 
c010807b:	c7 44 24 04 48 01 00 	movl   $0x148,0x4(%esp)
c0108082:	00 
c0108083:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c010808a:	e8 b6 8b ff ff       	call   c0100c45 <__panic>
        // 确认 VMA1 的起始和结束地址
        assert(vma1->vm_start == i  && vma1->vm_end == i  + 2);
c010808f:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0108092:	8b 50 04             	mov    0x4(%eax),%edx
c0108095:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108098:	39 c2                	cmp    %eax,%edx
c010809a:	75 10                	jne    c01080ac <check_vma_struct+0x37e>
c010809c:	8b 45 d8             	mov    -0x28(%ebp),%eax
c010809f:	8b 40 08             	mov    0x8(%eax),%eax
c01080a2:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01080a5:	83 c2 02             	add    $0x2,%edx
c01080a8:	39 d0                	cmp    %edx,%eax
c01080aa:	74 24                	je     c01080d0 <check_vma_struct+0x3a2>
c01080ac:	c7 44 24 0c 20 bc 10 	movl   $0xc010bc20,0xc(%esp)
c01080b3:	c0 
c01080b4:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c01080bb:	c0 
c01080bc:	c7 44 24 04 4a 01 00 	movl   $0x14a,0x4(%esp)
c01080c3:	00 
c01080c4:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c01080cb:	e8 75 8b ff ff       	call   c0100c45 <__panic>
        // 确认 VMA2 的起始和结束地址
        assert(vma2->vm_start == i  && vma2->vm_end == i  + 2);
c01080d0:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01080d3:	8b 50 04             	mov    0x4(%eax),%edx
c01080d6:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01080d9:	39 c2                	cmp    %eax,%edx
c01080db:	75 10                	jne    c01080ed <check_vma_struct+0x3bf>
c01080dd:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c01080e0:	8b 40 08             	mov    0x8(%eax),%eax
c01080e3:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01080e6:	83 c2 02             	add    $0x2,%edx
c01080e9:	39 d0                	cmp    %edx,%eax
c01080eb:	74 24                	je     c0108111 <check_vma_struct+0x3e3>
c01080ed:	c7 44 24 0c 50 bc 10 	movl   $0xc010bc50,0xc(%esp)
c01080f4:	c0 
c01080f5:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c01080fc:	c0 
c01080fd:	c7 44 24 04 4c 01 00 	movl   $0x14c,0x4(%esp)
c0108104:	00 
c0108105:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c010810c:	e8 34 8b ff ff       	call   c0100c45 <__panic>
    for (i = 5; i <= 5 * step2; i +=5) {// 查找特定地址范围内的 VMA
c0108111:	83 45 f4 05          	addl   $0x5,-0xc(%ebp)
c0108115:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0108118:	89 d0                	mov    %edx,%eax
c010811a:	c1 e0 02             	shl    $0x2,%eax
c010811d:	01 d0                	add    %edx,%eax
c010811f:	39 45 f4             	cmp    %eax,-0xc(%ebp)
c0108122:	0f 8e 22 fe ff ff    	jle    c0107f4a <check_vma_struct+0x21c>
    }
    // 检查小于5的地址范围内是否存在 VMA
    for (i =4; i>=0; i--) {
c0108128:	c7 45 f4 04 00 00 00 	movl   $0x4,-0xc(%ebp)
c010812f:	eb 6f                	jmp    c01081a0 <check_vma_struct+0x472>
        // 查找地址 i 处的 VMA
        struct vma_struct *vma_below_5= find_vma(mm,i);
c0108131:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108134:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108138:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010813b:	89 04 24             	mov    %eax,(%esp)
c010813e:	e8 ae f8 ff ff       	call   c01079f1 <find_vma>
c0108143:	89 45 dc             	mov    %eax,-0x24(%ebp)
        if (vma_below_5 != NULL ) {// 如果找到 VMA
c0108146:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c010814a:	74 27                	je     c0108173 <check_vma_struct+0x445>
           cprintf("vma_below_5: i %x, start %x, end %x\n",i, vma_below_5->vm_start, vma_below_5->vm_end); 
c010814c:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010814f:	8b 50 08             	mov    0x8(%eax),%edx
c0108152:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108155:	8b 40 04             	mov    0x4(%eax),%eax
c0108158:	89 54 24 0c          	mov    %edx,0xc(%esp)
c010815c:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108160:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108163:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108167:	c7 04 24 80 bc 10 c0 	movl   $0xc010bc80,(%esp)
c010816e:	e8 05 82 ff ff       	call   c0100378 <cprintf>
        }
        assert(vma_below_5 == NULL);// 确保未找到 VMA
c0108173:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0108177:	74 24                	je     c010819d <check_vma_struct+0x46f>
c0108179:	c7 44 24 0c a5 bc 10 	movl   $0xc010bca5,0xc(%esp)
c0108180:	c0 
c0108181:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0108188:	c0 
c0108189:	c7 44 24 04 55 01 00 	movl   $0x155,0x4(%esp)
c0108190:	00 
c0108191:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0108198:	e8 a8 8a ff ff       	call   c0100c45 <__panic>
    for (i =4; i>=0; i--) {
c010819d:	ff 4d f4             	decl   -0xc(%ebp)
c01081a0:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c01081a4:	79 8b                	jns    c0108131 <check_vma_struct+0x403>
    }

    mm_destroy(mm);// 销毁 mm 结构
c01081a6:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01081a9:	89 04 24             	mov    %eax,(%esp)
c01081ac:	e8 d0 fa ff ff       	call   c0107c81 <mm_destroy>

    // 确保释放的页面数量与初始记录一致
    // assert(nr_free_pages_store == nr_free_pages());
    // 输出成功信息
    cprintf("check_vma_struct() succeeded!\n");
c01081b1:	c7 04 24 bc bc 10 c0 	movl   $0xc010bcbc,(%esp)
c01081b8:	e8 bb 81 ff ff       	call   c0100378 <cprintf>
}
c01081bd:	90                   	nop
c01081be:	89 ec                	mov    %ebp,%esp
c01081c0:	5d                   	pop    %ebp
c01081c1:	c3                   	ret    

c01081c2 <check_pgfault>:
struct mm_struct *check_mm_struct;

// check_pgfault - check correctness of pgfault handler
// 检查页故障处理的正确性
static void
check_pgfault(void) {
c01081c2:	55                   	push   %ebp
c01081c3:	89 e5                	mov    %esp,%ebp
c01081c5:	83 ec 38             	sub    $0x38,%esp
    // 保存当前空闲页面的数量，用于后续检查
    size_t nr_free_pages_store = nr_free_pages();
c01081c8:	e8 b0 ce ff ff       	call   c010507d <nr_free_pages>
c01081cd:	89 45 ec             	mov    %eax,-0x14(%ebp)
    // 创建内存管理结构体
    check_mm_struct = mm_create();
c01081d0:	e8 64 f7 ff ff       	call   c0107939 <mm_create>
c01081d5:	a3 6c c1 12 c0       	mov    %eax,0xc012c16c
    // 确保内存管理结构体创建成功
    assert(check_mm_struct != NULL);
c01081da:	a1 6c c1 12 c0       	mov    0xc012c16c,%eax
c01081df:	85 c0                	test   %eax,%eax
c01081e1:	75 24                	jne    c0108207 <check_pgfault+0x45>
c01081e3:	c7 44 24 0c db bc 10 	movl   $0xc010bcdb,0xc(%esp)
c01081ea:	c0 
c01081eb:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c01081f2:	c0 
c01081f3:	c7 44 24 04 6b 01 00 	movl   $0x16b,0x4(%esp)
c01081fa:	00 
c01081fb:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0108202:	e8 3e 8a ff ff       	call   c0100c45 <__panic>
    // 将新创建的内存管理结构体赋值给局部变量mm
    struct mm_struct *mm = check_mm_struct;
c0108207:	a1 6c c1 12 c0       	mov    0xc012c16c,%eax
c010820c:	89 45 e8             	mov    %eax,-0x18(%ebp)
    // 将引导程序的页目录复制到新创建的内存管理结构体中
    pde_t *pgdir = mm->pgdir = boot_pgdir;
c010820f:	8b 15 00 8a 12 c0    	mov    0xc0128a00,%edx
c0108215:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108218:	89 50 0c             	mov    %edx,0xc(%eax)
c010821b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010821e:	8b 40 0c             	mov    0xc(%eax),%eax
c0108221:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    // 确保页目录的第0项是空的
    assert(pgdir[0] == 0);
c0108224:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108227:	8b 00                	mov    (%eax),%eax
c0108229:	85 c0                	test   %eax,%eax
c010822b:	74 24                	je     c0108251 <check_pgfault+0x8f>
c010822d:	c7 44 24 0c f3 bc 10 	movl   $0xc010bcf3,0xc(%esp)
c0108234:	c0 
c0108235:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c010823c:	c0 
c010823d:	c7 44 24 04 71 01 00 	movl   $0x171,0x4(%esp)
c0108244:	00 
c0108245:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c010824c:	e8 f4 89 ff ff       	call   c0100c45 <__panic>
    // 创建一个虚拟内存区域结构体，具有写权限
    struct vma_struct *vma = vma_create(0, PTSIZE, VM_WRITE);
c0108251:	c7 44 24 08 02 00 00 	movl   $0x2,0x8(%esp)
c0108258:	00 
c0108259:	c7 44 24 04 00 00 40 	movl   $0x400000,0x4(%esp)
c0108260:	00 
c0108261:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
c0108268:	e8 47 f7 ff ff       	call   c01079b4 <vma_create>
c010826d:	89 45 e0             	mov    %eax,-0x20(%ebp)
    // 确保虚拟内存区域结构体创建成功
    assert(vma != NULL);
c0108270:	83 7d e0 00          	cmpl   $0x0,-0x20(%ebp)
c0108274:	75 24                	jne    c010829a <check_pgfault+0xd8>
c0108276:	c7 44 24 0c 84 bb 10 	movl   $0xc010bb84,0xc(%esp)
c010827d:	c0 
c010827e:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0108285:	c0 
c0108286:	c7 44 24 04 75 01 00 	movl   $0x175,0x4(%esp)
c010828d:	00 
c010828e:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0108295:	e8 ab 89 ff ff       	call   c0100c45 <__panic>
    // 将虚拟内存区域结构体插入到内存管理结构体中
    insert_vma_struct(mm, vma);
c010829a:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010829d:	89 44 24 04          	mov    %eax,0x4(%esp)
c01082a1:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01082a4:	89 04 24             	mov    %eax,(%esp)
c01082a7:	e8 9f f8 ff ff       	call   c0107b4b <insert_vma_struct>
    // 定义一个地址，用于访问虚拟内存
    uintptr_t addr = 0x100;
c01082ac:	c7 45 dc 00 01 00 00 	movl   $0x100,-0x24(%ebp)
    // 确保通过该地址可以找到之前插入的虚拟内存区域
    assert(find_vma(mm, addr) == vma);
c01082b3:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01082b6:	89 44 24 04          	mov    %eax,0x4(%esp)
c01082ba:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01082bd:	89 04 24             	mov    %eax,(%esp)
c01082c0:	e8 2c f7 ff ff       	call   c01079f1 <find_vma>
c01082c5:	39 45 e0             	cmp    %eax,-0x20(%ebp)
c01082c8:	74 24                	je     c01082ee <check_pgfault+0x12c>
c01082ca:	c7 44 24 0c 01 bd 10 	movl   $0xc010bd01,0xc(%esp)
c01082d1:	c0 
c01082d2:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c01082d9:	c0 
c01082da:	c7 44 24 04 7b 01 00 	movl   $0x17b,0x4(%esp)
c01082e1:	00 
c01082e2:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c01082e9:	e8 57 89 ff ff       	call   c0100c45 <__panic>
    // 初始化一个累加器，用于校验写入的数据
    int i, sum = 0;
c01082ee:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    // 写入数据到虚拟内存，并累加
    for (i = 0; i < 100; i ++) {
c01082f5:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c01082fc:	eb 16                	jmp    c0108314 <check_pgfault+0x152>
        *(char *)(addr + i) = i;
c01082fe:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108301:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108304:	01 d0                	add    %edx,%eax
c0108306:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108309:	88 10                	mov    %dl,(%eax)
        sum += i;
c010830b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010830e:	01 45 f0             	add    %eax,-0x10(%ebp)
    for (i = 0; i < 100; i ++) {
c0108311:	ff 45 f4             	incl   -0xc(%ebp)
c0108314:	83 7d f4 63          	cmpl   $0x63,-0xc(%ebp)
c0108318:	7e e4                	jle    c01082fe <check_pgfault+0x13c>
    }
    // 读取虚拟内存中的数据，并减去，最终结果应为0
    for (i = 0; i < 100; i ++) {
c010831a:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0108321:	eb 14                	jmp    c0108337 <check_pgfault+0x175>
        sum -= *(char *)(addr + i);
c0108323:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0108326:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108329:	01 d0                	add    %edx,%eax
c010832b:	0f b6 00             	movzbl (%eax),%eax
c010832e:	0f be c0             	movsbl %al,%eax
c0108331:	29 45 f0             	sub    %eax,-0x10(%ebp)
    for (i = 0; i < 100; i ++) {
c0108334:	ff 45 f4             	incl   -0xc(%ebp)
c0108337:	83 7d f4 63          	cmpl   $0x63,-0xc(%ebp)
c010833b:	7e e6                	jle    c0108323 <check_pgfault+0x161>
    }
    // 确保累加器的值为0，证明数据读写正确
    assert(sum == 0);
c010833d:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0108341:	74 24                	je     c0108367 <check_pgfault+0x1a5>
c0108343:	c7 44 24 0c 1b bd 10 	movl   $0xc010bd1b,0xc(%esp)
c010834a:	c0 
c010834b:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c0108352:	c0 
c0108353:	c7 44 24 04 88 01 00 	movl   $0x188,0x4(%esp)
c010835a:	00 
c010835b:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c0108362:	e8 de 88 ff ff       	call   c0100c45 <__panic>
    // 移除页目录中的相应页面
    page_remove(pgdir, ROUNDDOWN(addr, PGSIZE));
c0108367:	8b 45 dc             	mov    -0x24(%ebp),%eax
c010836a:	89 45 d8             	mov    %eax,-0x28(%ebp)
c010836d:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0108370:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c0108375:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108379:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010837c:	89 04 24             	mov    %eax,(%esp)
c010837f:	e8 0c d5 ff ff       	call   c0105890 <page_remove>
    // 释放第0项页目录对应的页面
    free_page(pde2page(pgdir[0]));
c0108384:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108387:	8b 00                	mov    (%eax),%eax
c0108389:	89 04 24             	mov    %eax,(%esp)
c010838c:	e8 8e f5 ff ff       	call   c010791f <pde2page>
c0108391:	c7 44 24 04 01 00 00 	movl   $0x1,0x4(%esp)
c0108398:	00 
c0108399:	89 04 24             	mov    %eax,(%esp)
c010839c:	e8 a7 cc ff ff       	call   c0105048 <free_pages>
    // 将页目录的第0项设置为空
    pgdir[0] = 0;
c01083a1:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01083a4:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
    // 将内存管理结构体中的页目录设置为空
    mm->pgdir = NULL;
c01083aa:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01083ad:	c7 40 0c 00 00 00 00 	movl   $0x0,0xc(%eax)
    // 销毁内存管理结构体
    mm_destroy(mm);
c01083b4:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01083b7:	89 04 24             	mov    %eax,(%esp)
c01083ba:	e8 c2 f8 ff ff       	call   c0107c81 <mm_destroy>
    // 将检查用的内存管理结构体设置为空
    check_mm_struct = NULL;
c01083bf:	c7 05 6c c1 12 c0 00 	movl   $0x0,0xc012c16c
c01083c6:	00 00 00 
    // 确保空闲页面的数量没有变化，证明内存管理正确
    assert(nr_free_pages_store == nr_free_pages());
c01083c9:	e8 af cc ff ff       	call   c010507d <nr_free_pages>
c01083ce:	39 45 ec             	cmp    %eax,-0x14(%ebp)
c01083d1:	74 24                	je     c01083f7 <check_pgfault+0x235>
c01083d3:	c7 44 24 0c 24 bd 10 	movl   $0xc010bd24,0xc(%esp)
c01083da:	c0 
c01083db:	c7 44 24 08 e3 ba 10 	movl   $0xc010bae3,0x8(%esp)
c01083e2:	c0 
c01083e3:	c7 44 24 04 96 01 00 	movl   $0x196,0x4(%esp)
c01083ea:	00 
c01083eb:	c7 04 24 f8 ba 10 c0 	movl   $0xc010baf8,(%esp)
c01083f2:	e8 4e 88 ff ff       	call   c0100c45 <__panic>
    // 打印成功信息
    cprintf("check_pgfault() succeeded!\n");
c01083f7:	c7 04 24 4b bd 10 c0 	movl   $0xc010bd4b,(%esp)
c01083fe:	e8 75 7f ff ff       	call   c0100378 <cprintf>
}
c0108403:	90                   	nop
c0108404:	89 ec                	mov    %ebp,%esp
c0108406:	5d                   	pop    %ebp
c0108407:	c3                   	ret    

c0108408 <do_pgfault>:
 * @param addr 引发页面错误的线性地址。
 * 
 * @return 成功返回0，失败返回负错误码。
 */
int
do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
c0108408:	55                   	push   %ebp
c0108409:	89 e5                	mov    %esp,%ebp
c010840b:	83 ec 38             	sub    $0x38,%esp
    int ret = -E_INVAL;// 初始化返回值为无效错误
c010840e:	c7 45 f4 fd ff ff ff 	movl   $0xfffffffd,-0xc(%ebp)
    //try to find a vma which include addr
    // 尝试找到包含 addr 的 vma
    struct vma_struct *vma = find_vma(mm, addr);
c0108415:	8b 45 10             	mov    0x10(%ebp),%eax
c0108418:	89 44 24 04          	mov    %eax,0x4(%esp)
c010841c:	8b 45 08             	mov    0x8(%ebp),%eax
c010841f:	89 04 24             	mov    %eax,(%esp)
c0108422:	e8 ca f5 ff ff       	call   c01079f1 <find_vma>
c0108427:	89 45 ec             	mov    %eax,-0x14(%ebp)

    pgfault_num++;// 增加页面错误计数
c010842a:	a1 70 c1 12 c0       	mov    0xc012c170,%eax
c010842f:	40                   	inc    %eax
c0108430:	a3 70 c1 12 c0       	mov    %eax,0xc012c170
    // 检查 addr 是否在 mm 的 vma 范围内
    //If the addr is in the range of a mm's vma?
    if (vma == NULL || vma->vm_start > addr) {
c0108435:	83 7d ec 00          	cmpl   $0x0,-0x14(%ebp)
c0108439:	74 0b                	je     c0108446 <do_pgfault+0x3e>
c010843b:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010843e:	8b 40 04             	mov    0x4(%eax),%eax
c0108441:	39 45 10             	cmp    %eax,0x10(%ebp)
c0108444:	73 18                	jae    c010845e <do_pgfault+0x56>
        cprintf("not valid addr %x, and  can not find it in vma\n", addr);
c0108446:	8b 45 10             	mov    0x10(%ebp),%eax
c0108449:	89 44 24 04          	mov    %eax,0x4(%esp)
c010844d:	c7 04 24 68 bd 10 c0 	movl   $0xc010bd68,(%esp)
c0108454:	e8 1f 7f ff ff       	call   c0100378 <cprintf>
        goto failed;// 跳转到错误处理部分
c0108459:	e9 ba 01 00 00       	jmp    c0108618 <do_pgfault+0x210>
    }
    //check the error_code
    // 检查错误代码
    switch (error_code & 3) {
c010845e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108461:	83 e0 03             	and    $0x3,%eax
c0108464:	85 c0                	test   %eax,%eax
c0108466:	74 34                	je     c010849c <do_pgfault+0x94>
c0108468:	83 f8 01             	cmp    $0x1,%eax
c010846b:	74 1e                	je     c010848b <do_pgfault+0x83>
    default:
            /* 默认错误代码标志：3 (W/R=1, P=1): 写操作，存在 */
            /* error code flag : default is 3 ( W/R=1, P=1): write, present */
    case 2: /* error code flag : (W/R=1, P=0): write, not present */
            /* 错误代码标志：(W/R=1, P=0): 写操作，不存在 */
        if (!(vma->vm_flags & VM_WRITE)) {
c010846d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108470:	8b 40 0c             	mov    0xc(%eax),%eax
c0108473:	83 e0 02             	and    $0x2,%eax
c0108476:	85 c0                	test   %eax,%eax
c0108478:	75 40                	jne    c01084ba <do_pgfault+0xb2>
            cprintf("do_pgfault failed: error code flag = write AND not present, but the addr's vma cannot write\n");
c010847a:	c7 04 24 98 bd 10 c0 	movl   $0xc010bd98,(%esp)
c0108481:	e8 f2 7e ff ff       	call   c0100378 <cprintf>
            goto failed;// 跳转到错误处理部分
c0108486:	e9 8d 01 00 00       	jmp    c0108618 <do_pgfault+0x210>
        }
        break;
    case 1: /* error code flag : (W/R=0, P=1): read, present */
            /* 错误代码标志：(W/R=0, P=1): 读操作，存在 */
        cprintf("do_pgfault failed: error code flag = read AND present\n");
c010848b:	c7 04 24 f8 bd 10 c0 	movl   $0xc010bdf8,(%esp)
c0108492:	e8 e1 7e ff ff       	call   c0100378 <cprintf>
        goto failed;// 跳转到错误处理部分
c0108497:	e9 7c 01 00 00       	jmp    c0108618 <do_pgfault+0x210>
    case 0: /* error code flag : (W/R=0, P=0): read, not present */
             /* 错误代码标志：(W/R=0, P=0): 读操作，不存在 */
        if (!(vma->vm_flags & (VM_READ | VM_EXEC))) {
c010849c:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010849f:	8b 40 0c             	mov    0xc(%eax),%eax
c01084a2:	83 e0 05             	and    $0x5,%eax
c01084a5:	85 c0                	test   %eax,%eax
c01084a7:	75 12                	jne    c01084bb <do_pgfault+0xb3>
            cprintf("do_pgfault failed: error code flag = read AND not present, but the addr's vma cannot read or exec\n");
c01084a9:	c7 04 24 30 be 10 c0 	movl   $0xc010be30,(%esp)
c01084b0:	e8 c3 7e ff ff       	call   c0100378 <cprintf>
            goto failed;// 跳转到错误处理部分
c01084b5:	e9 5e 01 00 00       	jmp    c0108618 <do_pgfault+0x210>
        break;
c01084ba:	90                   	nop
    /* 如果 (写入已存在的地址) 或
     *    (写入不存在的地址且地址可写) 或
     *    (读取不存在的地址且地址可读)
     * 则继续处理
     */
    uint32_t perm = PTE_U;// 初始化权限标志为用户可访问
c01084bb:	c7 45 f0 04 00 00 00 	movl   $0x4,-0x10(%ebp)
    if (vma->vm_flags & VM_WRITE) {
c01084c2:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01084c5:	8b 40 0c             	mov    0xc(%eax),%eax
c01084c8:	83 e0 02             	and    $0x2,%eax
c01084cb:	85 c0                	test   %eax,%eax
c01084cd:	74 04                	je     c01084d3 <do_pgfault+0xcb>
        perm |= PTE_W;// 如果 vma 可写，则设置写权限
c01084cf:	83 4d f0 02          	orl    $0x2,-0x10(%ebp)
    }
    addr = ROUNDDOWN(addr, PGSIZE);// 将地址对齐到页边界
c01084d3:	8b 45 10             	mov    0x10(%ebp),%eax
c01084d6:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01084d9:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01084dc:	25 00 f0 ff ff       	and    $0xfffff000,%eax
c01084e1:	89 45 10             	mov    %eax,0x10(%ebp)

    ret = -E_NO_MEM;// 初始化返回值为内存不足错误
c01084e4:	c7 45 f4 fc ff ff ff 	movl   $0xfffffffc,-0xc(%ebp)

    pte_t *ptep=NULL;
c01084eb:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
#endif
    // try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT.
    // (notice the 3th parameter '1')
    // 尝试找到一个页表项 pte，如果包含该 pte 的页表不存在，则创建一个页表。
    // 注意第三个参数 '1' 表示如果需要，可以创建新的页表。
    if ((ptep = get_pte(mm->pgdir, addr, 1)) == NULL) {
c01084f2:	8b 45 08             	mov    0x8(%ebp),%eax
c01084f5:	8b 40 0c             	mov    0xc(%eax),%eax
c01084f8:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
c01084ff:	00 
c0108500:	8b 55 10             	mov    0x10(%ebp),%edx
c0108503:	89 54 24 04          	mov    %edx,0x4(%esp)
c0108507:	89 04 24             	mov    %eax,(%esp)
c010850a:	e8 87 d1 ff ff       	call   c0105696 <get_pte>
c010850f:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0108512:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0108516:	75 11                	jne    c0108529 <do_pgfault+0x121>
        cprintf("get_pte in do_pgfault failed\n");// 输出错误信息
c0108518:	c7 04 24 93 be 10 c0 	movl   $0xc010be93,(%esp)
c010851f:	e8 54 7e ff ff       	call   c0100378 <cprintf>
        goto failed;// 跳转到错误处理部分
c0108524:	e9 ef 00 00 00       	jmp    c0108618 <do_pgfault+0x210>
    }
    // 如果页表项 pte 的物理地址不存在，则分配一页内存并映射物理地址与逻辑地址
    if (*ptep == 0) { // if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr
c0108529:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010852c:	8b 00                	mov    (%eax),%eax
c010852e:	85 c0                	test   %eax,%eax
c0108530:	75 35                	jne    c0108567 <do_pgfault+0x15f>
        if (pgdir_alloc_page(mm->pgdir, addr, perm) == NULL) {
c0108532:	8b 45 08             	mov    0x8(%ebp),%eax
c0108535:	8b 40 0c             	mov    0xc(%eax),%eax
c0108538:	8b 55 f0             	mov    -0x10(%ebp),%edx
c010853b:	89 54 24 08          	mov    %edx,0x8(%esp)
c010853f:	8b 55 10             	mov    0x10(%ebp),%edx
c0108542:	89 54 24 04          	mov    %edx,0x4(%esp)
c0108546:	89 04 24             	mov    %eax,(%esp)
c0108549:	e8 a3 d4 ff ff       	call   c01059f1 <pgdir_alloc_page>
c010854e:	85 c0                	test   %eax,%eax
c0108550:	0f 85 bb 00 00 00    	jne    c0108611 <do_pgfault+0x209>
            cprintf("pgdir_alloc_page in do_pgfault failed\n");// 输出错误信息
c0108556:	c7 04 24 b4 be 10 c0 	movl   $0xc010beb4,(%esp)
c010855d:	e8 16 7e ff ff       	call   c0100378 <cprintf>
            goto failed;// 跳转到错误处理部分
c0108562:	e9 b1 00 00 00       	jmp    c0108618 <do_pgfault+0x210>
    }
    else { // if this pte is a swap entry, then load data from disk to a page with phy addr
           // and call page_insert to map the phy addr with logical addr
           // 如果页表项 pte 是一个交换项，则从磁盘加载数据到
           //一个具有物理地址的页面，并映射物理地址与逻辑地址
        if(swap_init_ok) {// 检查交换初始化是否成功
c0108567:	a1 a4 c0 12 c0       	mov    0xc012c0a4,%eax
c010856c:	85 c0                	test   %eax,%eax
c010856e:	0f 84 86 00 00 00    	je     c01085fa <do_pgfault+0x1f2>
            struct Page *page=NULL;// 声明一个页面指针
c0108574:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
            if ((ret = swap_in(mm, addr, &page)) != 0) {
c010857b:	8d 45 e0             	lea    -0x20(%ebp),%eax
c010857e:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108582:	8b 45 10             	mov    0x10(%ebp),%eax
c0108585:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108589:	8b 45 08             	mov    0x8(%ebp),%eax
c010858c:	89 04 24             	mov    %eax,(%esp)
c010858f:	e8 e8 e4 ff ff       	call   c0106a7c <swap_in>
c0108594:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108597:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010859b:	74 0e                	je     c01085ab <do_pgfault+0x1a3>
                cprintf("swap_in in do_pgfault failed\n");
c010859d:	c7 04 24 db be 10 c0 	movl   $0xc010bedb,(%esp)
c01085a4:	e8 cf 7d ff ff       	call   c0100378 <cprintf>
c01085a9:	eb 6d                	jmp    c0108618 <do_pgfault+0x210>
                goto failed;
            }    
            page_insert(mm->pgdir, page, addr, perm);// 设置物理地址与逻辑地址的映射
c01085ab:	8b 55 e0             	mov    -0x20(%ebp),%edx
c01085ae:	8b 45 08             	mov    0x8(%ebp),%eax
c01085b1:	8b 40 0c             	mov    0xc(%eax),%eax
c01085b4:	8b 4d f0             	mov    -0x10(%ebp),%ecx
c01085b7:	89 4c 24 0c          	mov    %ecx,0xc(%esp)
c01085bb:	8b 4d 10             	mov    0x10(%ebp),%ecx
c01085be:	89 4c 24 08          	mov    %ecx,0x8(%esp)
c01085c2:	89 54 24 04          	mov    %edx,0x4(%esp)
c01085c6:	89 04 24             	mov    %eax,(%esp)
c01085c9:	e8 09 d3 ff ff       	call   c01058d7 <page_insert>
            swap_map_swappable(mm, addr, page, 1);// 设置页面可交换
c01085ce:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01085d1:	c7 44 24 0c 01 00 00 	movl   $0x1,0xc(%esp)
c01085d8:	00 
c01085d9:	89 44 24 08          	mov    %eax,0x8(%esp)
c01085dd:	8b 45 10             	mov    0x10(%ebp),%eax
c01085e0:	89 44 24 04          	mov    %eax,0x4(%esp)
c01085e4:	8b 45 08             	mov    0x8(%ebp),%eax
c01085e7:	89 04 24             	mov    %eax,(%esp)
c01085ea:	e8 c5 e2 ff ff       	call   c01068b4 <swap_map_swappable>
            page->pra_vaddr = addr;// 记录页面的虚拟地址
c01085ef:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01085f2:	8b 55 10             	mov    0x10(%ebp),%edx
c01085f5:	89 50 1c             	mov    %edx,0x1c(%eax)
c01085f8:	eb 17                	jmp    c0108611 <do_pgfault+0x209>
        }
        else {
            cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep);
c01085fa:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01085fd:	8b 00                	mov    (%eax),%eax
c01085ff:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108603:	c7 04 24 fc be 10 c0 	movl   $0xc010befc,(%esp)
c010860a:	e8 69 7d ff ff       	call   c0100378 <cprintf>
            goto failed;// 跳转到错误处理部分
c010860f:	eb 07                	jmp    c0108618 <do_pgfault+0x210>
        }
   }
   ret = 0;// 设置返回值为成功
c0108611:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
failed:
    return ret;// 返回结果
c0108618:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c010861b:	89 ec                	mov    %ebp,%esp
c010861d:	5d                   	pop    %ebp
c010861e:	c3                   	ret    

c010861f <page2ppn>:
page2ppn(struct Page *page) {
c010861f:	55                   	push   %ebp
c0108620:	89 e5                	mov    %esp,%ebp
    return page - pages;
c0108622:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c0108628:	8b 45 08             	mov    0x8(%ebp),%eax
c010862b:	29 d0                	sub    %edx,%eax
c010862d:	c1 f8 05             	sar    $0x5,%eax
}
c0108630:	5d                   	pop    %ebp
c0108631:	c3                   	ret    

c0108632 <page2pa>:
page2pa(struct Page *page) {
c0108632:	55                   	push   %ebp
c0108633:	89 e5                	mov    %esp,%ebp
c0108635:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c0108638:	8b 45 08             	mov    0x8(%ebp),%eax
c010863b:	89 04 24             	mov    %eax,(%esp)
c010863e:	e8 dc ff ff ff       	call   c010861f <page2ppn>
c0108643:	c1 e0 0c             	shl    $0xc,%eax
}
c0108646:	89 ec                	mov    %ebp,%esp
c0108648:	5d                   	pop    %ebp
c0108649:	c3                   	ret    

c010864a <page2kva>:
page2kva(struct Page *page) {
c010864a:	55                   	push   %ebp
c010864b:	89 e5                	mov    %esp,%ebp
c010864d:	83 ec 28             	sub    $0x28,%esp
    return KADDR(page2pa(page));
c0108650:	8b 45 08             	mov    0x8(%ebp),%eax
c0108653:	89 04 24             	mov    %eax,(%esp)
c0108656:	e8 d7 ff ff ff       	call   c0108632 <page2pa>
c010865b:	89 45 f4             	mov    %eax,-0xc(%ebp)
c010865e:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108661:	c1 e8 0c             	shr    $0xc,%eax
c0108664:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108667:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c010866c:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c010866f:	72 23                	jb     c0108694 <page2kva+0x4a>
c0108671:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108674:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0108678:	c7 44 24 08 24 bf 10 	movl   $0xc010bf24,0x8(%esp)
c010867f:	c0 
c0108680:	c7 44 24 04 66 00 00 	movl   $0x66,0x4(%esp)
c0108687:	00 
c0108688:	c7 04 24 47 bf 10 c0 	movl   $0xc010bf47,(%esp)
c010868f:	e8 b1 85 ff ff       	call   c0100c45 <__panic>
c0108694:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108697:	2d 00 00 00 40       	sub    $0x40000000,%eax
}
c010869c:	89 ec                	mov    %ebp,%esp
c010869e:	5d                   	pop    %ebp
c010869f:	c3                   	ret    

c01086a0 <swapfs_init>:
#include <ide.h>
#include <pmm.h>
#include <assert.h>

void
swapfs_init(void) {
c01086a0:	55                   	push   %ebp
c01086a1:	89 e5                	mov    %esp,%ebp
c01086a3:	83 ec 18             	sub    $0x18,%esp
    static_assert((PGSIZE % SECTSIZE) == 0);
    if (!ide_device_valid(SWAP_DEV_NO)) {
c01086a6:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01086ad:	e8 42 93 ff ff       	call   c01019f4 <ide_device_valid>
c01086b2:	85 c0                	test   %eax,%eax
c01086b4:	75 1c                	jne    c01086d2 <swapfs_init+0x32>
        panic("swap fs isn't available.\n");
c01086b6:	c7 44 24 08 55 bf 10 	movl   $0xc010bf55,0x8(%esp)
c01086bd:	c0 
c01086be:	c7 44 24 04 0d 00 00 	movl   $0xd,0x4(%esp)
c01086c5:	00 
c01086c6:	c7 04 24 6f bf 10 c0 	movl   $0xc010bf6f,(%esp)
c01086cd:	e8 73 85 ff ff       	call   c0100c45 <__panic>
    }
    max_swap_offset = ide_device_size(SWAP_DEV_NO) / (PGSIZE / SECTSIZE);
c01086d2:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01086d9:	e8 56 93 ff ff       	call   c0101a34 <ide_device_size>
c01086de:	c1 e8 03             	shr    $0x3,%eax
c01086e1:	a3 a0 c0 12 c0       	mov    %eax,0xc012c0a0
}
c01086e6:	90                   	nop
c01086e7:	89 ec                	mov    %ebp,%esp
c01086e9:	5d                   	pop    %ebp
c01086ea:	c3                   	ret    

c01086eb <swapfs_read>:

int
swapfs_read(swap_entry_t entry, struct Page *page) {
c01086eb:	55                   	push   %ebp
c01086ec:	89 e5                	mov    %esp,%ebp
c01086ee:	83 ec 28             	sub    $0x28,%esp
    return ide_read_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT);
c01086f1:	8b 45 0c             	mov    0xc(%ebp),%eax
c01086f4:	89 04 24             	mov    %eax,(%esp)
c01086f7:	e8 4e ff ff ff       	call   c010864a <page2kva>
c01086fc:	8b 55 08             	mov    0x8(%ebp),%edx
c01086ff:	c1 ea 08             	shr    $0x8,%edx
c0108702:	89 55 f4             	mov    %edx,-0xc(%ebp)
c0108705:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0108709:	74 0b                	je     c0108716 <swapfs_read+0x2b>
c010870b:	8b 15 a0 c0 12 c0    	mov    0xc012c0a0,%edx
c0108711:	39 55 f4             	cmp    %edx,-0xc(%ebp)
c0108714:	72 23                	jb     c0108739 <swapfs_read+0x4e>
c0108716:	8b 45 08             	mov    0x8(%ebp),%eax
c0108719:	89 44 24 0c          	mov    %eax,0xc(%esp)
c010871d:	c7 44 24 08 80 bf 10 	movl   $0xc010bf80,0x8(%esp)
c0108724:	c0 
c0108725:	c7 44 24 04 14 00 00 	movl   $0x14,0x4(%esp)
c010872c:	00 
c010872d:	c7 04 24 6f bf 10 c0 	movl   $0xc010bf6f,(%esp)
c0108734:	e8 0c 85 ff ff       	call   c0100c45 <__panic>
c0108739:	8b 55 f4             	mov    -0xc(%ebp),%edx
c010873c:	c1 e2 03             	shl    $0x3,%edx
c010873f:	c7 44 24 0c 08 00 00 	movl   $0x8,0xc(%esp)
c0108746:	00 
c0108747:	89 44 24 08          	mov    %eax,0x8(%esp)
c010874b:	89 54 24 04          	mov    %edx,0x4(%esp)
c010874f:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c0108756:	e8 16 93 ff ff       	call   c0101a71 <ide_read_secs>
}
c010875b:	89 ec                	mov    %ebp,%esp
c010875d:	5d                   	pop    %ebp
c010875e:	c3                   	ret    

c010875f <swapfs_write>:

int
swapfs_write(swap_entry_t entry, struct Page *page) {
c010875f:	55                   	push   %ebp
c0108760:	89 e5                	mov    %esp,%ebp
c0108762:	83 ec 28             	sub    $0x28,%esp
    return ide_write_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT);
c0108765:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108768:	89 04 24             	mov    %eax,(%esp)
c010876b:	e8 da fe ff ff       	call   c010864a <page2kva>
c0108770:	8b 55 08             	mov    0x8(%ebp),%edx
c0108773:	c1 ea 08             	shr    $0x8,%edx
c0108776:	89 55 f4             	mov    %edx,-0xc(%ebp)
c0108779:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010877d:	74 0b                	je     c010878a <swapfs_write+0x2b>
c010877f:	8b 15 a0 c0 12 c0    	mov    0xc012c0a0,%edx
c0108785:	39 55 f4             	cmp    %edx,-0xc(%ebp)
c0108788:	72 23                	jb     c01087ad <swapfs_write+0x4e>
c010878a:	8b 45 08             	mov    0x8(%ebp),%eax
c010878d:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0108791:	c7 44 24 08 80 bf 10 	movl   $0xc010bf80,0x8(%esp)
c0108798:	c0 
c0108799:	c7 44 24 04 19 00 00 	movl   $0x19,0x4(%esp)
c01087a0:	00 
c01087a1:	c7 04 24 6f bf 10 c0 	movl   $0xc010bf6f,(%esp)
c01087a8:	e8 98 84 ff ff       	call   c0100c45 <__panic>
c01087ad:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01087b0:	c1 e2 03             	shl    $0x3,%edx
c01087b3:	c7 44 24 0c 08 00 00 	movl   $0x8,0xc(%esp)
c01087ba:	00 
c01087bb:	89 44 24 08          	mov    %eax,0x8(%esp)
c01087bf:	89 54 24 04          	mov    %edx,0x4(%esp)
c01087c3:	c7 04 24 01 00 00 00 	movl   $0x1,(%esp)
c01087ca:	e8 e3 94 ff ff       	call   c0101cb2 <ide_write_secs>
}
c01087cf:	89 ec                	mov    %ebp,%esp
c01087d1:	5d                   	pop    %ebp
c01087d2:	c3                   	ret    

c01087d3 <kernel_thread_entry>:
.text
.globl kernel_thread_entry
kernel_thread_entry:        # void kernel_thread(void)

    pushl %edx              # push arg
c01087d3:	52                   	push   %edx
    call *%ebx              # call fn
c01087d4:	ff d3                	call   *%ebx

    pushl %eax              # save the return value of fn(arg)
c01087d6:	50                   	push   %eax
    call do_exit            # call do_exit to terminate current thread
c01087d7:	e8 88 08 00 00       	call   c0109064 <do_exit>

c01087dc <__intr_save>:
__intr_save(void) {
c01087dc:	55                   	push   %ebp
c01087dd:	89 e5                	mov    %esp,%ebp
c01087df:	83 ec 18             	sub    $0x18,%esp
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c01087e2:	9c                   	pushf  
c01087e3:	58                   	pop    %eax
c01087e4:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c01087e7:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c01087ea:	25 00 02 00 00       	and    $0x200,%eax
c01087ef:	85 c0                	test   %eax,%eax
c01087f1:	74 0c                	je     c01087ff <__intr_save+0x23>
        intr_disable();
c01087f3:	e8 03 97 ff ff       	call   c0101efb <intr_disable>
        return 1;
c01087f8:	b8 01 00 00 00       	mov    $0x1,%eax
c01087fd:	eb 05                	jmp    c0108804 <__intr_save+0x28>
    return 0;
c01087ff:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0108804:	89 ec                	mov    %ebp,%esp
c0108806:	5d                   	pop    %ebp
c0108807:	c3                   	ret    

c0108808 <__intr_restore>:
__intr_restore(bool flag) {
c0108808:	55                   	push   %ebp
c0108809:	89 e5                	mov    %esp,%ebp
c010880b:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c010880e:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0108812:	74 05                	je     c0108819 <__intr_restore+0x11>
        intr_enable();
c0108814:	e8 da 96 ff ff       	call   c0101ef3 <intr_enable>
}
c0108819:	90                   	nop
c010881a:	89 ec                	mov    %ebp,%esp
c010881c:	5d                   	pop    %ebp
c010881d:	c3                   	ret    

c010881e <page2ppn>:
page2ppn(struct Page *page) {
c010881e:	55                   	push   %ebp
c010881f:	89 e5                	mov    %esp,%ebp
    return page - pages;
c0108821:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c0108827:	8b 45 08             	mov    0x8(%ebp),%eax
c010882a:	29 d0                	sub    %edx,%eax
c010882c:	c1 f8 05             	sar    $0x5,%eax
}
c010882f:	5d                   	pop    %ebp
c0108830:	c3                   	ret    

c0108831 <page2pa>:
page2pa(struct Page *page) {
c0108831:	55                   	push   %ebp
c0108832:	89 e5                	mov    %esp,%ebp
c0108834:	83 ec 04             	sub    $0x4,%esp
    return page2ppn(page) << PGSHIFT;
c0108837:	8b 45 08             	mov    0x8(%ebp),%eax
c010883a:	89 04 24             	mov    %eax,(%esp)
c010883d:	e8 dc ff ff ff       	call   c010881e <page2ppn>
c0108842:	c1 e0 0c             	shl    $0xc,%eax
}
c0108845:	89 ec                	mov    %ebp,%esp
c0108847:	5d                   	pop    %ebp
c0108848:	c3                   	ret    

c0108849 <pa2page>:
pa2page(uintptr_t pa) {
c0108849:	55                   	push   %ebp
c010884a:	89 e5                	mov    %esp,%ebp
c010884c:	83 ec 18             	sub    $0x18,%esp
    if (PPN(pa) >= npage) {
c010884f:	8b 45 08             	mov    0x8(%ebp),%eax
c0108852:	c1 e8 0c             	shr    $0xc,%eax
c0108855:	89 c2                	mov    %eax,%edx
c0108857:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c010885c:	39 c2                	cmp    %eax,%edx
c010885e:	72 1c                	jb     c010887c <pa2page+0x33>
        panic("pa2page called with invalid pa");
c0108860:	c7 44 24 08 a0 bf 10 	movl   $0xc010bfa0,0x8(%esp)
c0108867:	c0 
c0108868:	c7 44 24 04 5f 00 00 	movl   $0x5f,0x4(%esp)
c010886f:	00 
c0108870:	c7 04 24 bf bf 10 c0 	movl   $0xc010bfbf,(%esp)
c0108877:	e8 c9 83 ff ff       	call   c0100c45 <__panic>
    return &pages[PPN(pa)];
c010887c:	8b 15 00 c0 12 c0    	mov    0xc012c000,%edx
c0108882:	8b 45 08             	mov    0x8(%ebp),%eax
c0108885:	c1 e8 0c             	shr    $0xc,%eax
c0108888:	c1 e0 05             	shl    $0x5,%eax
c010888b:	01 d0                	add    %edx,%eax
}
c010888d:	89 ec                	mov    %ebp,%esp
c010888f:	5d                   	pop    %ebp
c0108890:	c3                   	ret    

c0108891 <page2kva>:
page2kva(struct Page *page) {
c0108891:	55                   	push   %ebp
c0108892:	89 e5                	mov    %esp,%ebp
c0108894:	83 ec 28             	sub    $0x28,%esp
    return KADDR(page2pa(page));
c0108897:	8b 45 08             	mov    0x8(%ebp),%eax
c010889a:	89 04 24             	mov    %eax,(%esp)
c010889d:	e8 8f ff ff ff       	call   c0108831 <page2pa>
c01088a2:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01088a5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01088a8:	c1 e8 0c             	shr    $0xc,%eax
c01088ab:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01088ae:	a1 04 c0 12 c0       	mov    0xc012c004,%eax
c01088b3:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c01088b6:	72 23                	jb     c01088db <page2kva+0x4a>
c01088b8:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01088bb:	89 44 24 0c          	mov    %eax,0xc(%esp)
c01088bf:	c7 44 24 08 d0 bf 10 	movl   $0xc010bfd0,0x8(%esp)
c01088c6:	c0 
c01088c7:	c7 44 24 04 66 00 00 	movl   $0x66,0x4(%esp)
c01088ce:	00 
c01088cf:	c7 04 24 bf bf 10 c0 	movl   $0xc010bfbf,(%esp)
c01088d6:	e8 6a 83 ff ff       	call   c0100c45 <__panic>
c01088db:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01088de:	2d 00 00 00 40       	sub    $0x40000000,%eax
}
c01088e3:	89 ec                	mov    %ebp,%esp
c01088e5:	5d                   	pop    %ebp
c01088e6:	c3                   	ret    

c01088e7 <kva2page>:
kva2page(void *kva) {
c01088e7:	55                   	push   %ebp
c01088e8:	89 e5                	mov    %esp,%ebp
c01088ea:	83 ec 28             	sub    $0x28,%esp
    return pa2page(PADDR(kva));
c01088ed:	8b 45 08             	mov    0x8(%ebp),%eax
c01088f0:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01088f3:	81 7d f4 ff ff ff bf 	cmpl   $0xbfffffff,-0xc(%ebp)
c01088fa:	77 23                	ja     c010891f <kva2page+0x38>
c01088fc:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01088ff:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0108903:	c7 44 24 08 f4 bf 10 	movl   $0xc010bff4,0x8(%esp)
c010890a:	c0 
c010890b:	c7 44 24 04 6b 00 00 	movl   $0x6b,0x4(%esp)
c0108912:	00 
c0108913:	c7 04 24 bf bf 10 c0 	movl   $0xc010bfbf,(%esp)
c010891a:	e8 26 83 ff ff       	call   c0100c45 <__panic>
c010891f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108922:	05 00 00 00 40       	add    $0x40000000,%eax
c0108927:	89 04 24             	mov    %eax,(%esp)
c010892a:	e8 1a ff ff ff       	call   c0108849 <pa2page>
}
c010892f:	89 ec                	mov    %ebp,%esp
c0108931:	5d                   	pop    %ebp
c0108932:	c3                   	ret    

c0108933 <alloc_proc>:
void forkrets(struct trapframe *tf);
void switch_to(struct context *from, struct context *to);

// alloc_proc - alloc a proc_struct and init all fields of proc_struct
static struct proc_struct *
alloc_proc(void) {
c0108933:	55                   	push   %ebp
c0108934:	89 e5                	mov    %esp,%ebp
c0108936:	83 ec 28             	sub    $0x28,%esp
    struct proc_struct *proc = kmalloc(sizeof(struct proc_struct));
c0108939:	c7 04 24 68 00 00 00 	movl   $0x68,(%esp)
c0108940:	e8 05 c2 ff ff       	call   c0104b4a <kmalloc>
c0108945:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (proc != NULL) {
c0108948:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c010894c:	0f 84 a1 00 00 00    	je     c01089f3 <alloc_proc+0xc0>
     *       struct trapframe *tf;                       // Trap frame for current interrupt
     *       uintptr_t cr3;                              // CR3 register: the base addr of Page Directroy Table(PDT)
     *       uint32_t flags;                             // Process flag
     *       char name[PROC_NAME_LEN + 1];               // Process name
     */
        proc->state = PROC_UNINIT; // 初始状态为未初始化
c0108952:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108955:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
        proc->pid = -1;            // 初始进程ID为-1
c010895b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010895e:	c7 40 04 ff ff ff ff 	movl   $0xffffffff,0x4(%eax)
        proc->runs = 0;            // 初始运行次数为0
c0108965:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108968:	c7 40 08 00 00 00 00 	movl   $0x0,0x8(%eax)
        proc->kstack = 0;          // 初始内核栈指针为0
c010896f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108972:	c7 40 0c 00 00 00 00 	movl   $0x0,0xc(%eax)
        proc->need_resched = 0;    // 初始不需要重新调度
c0108979:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010897c:	c7 40 10 00 00 00 00 	movl   $0x0,0x10(%eax)
        proc->parent = NULL;       // 初始父进程指针为NULL
c0108983:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108986:	c7 40 14 00 00 00 00 	movl   $0x0,0x14(%eax)
        proc->mm = NULL;           // 初始内存管理结构指针为NULL
c010898d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108990:	c7 40 18 00 00 00 00 	movl   $0x0,0x18(%eax)
        memset(&proc->context, 0, sizeof(struct context));  // 初始化上下文切换信息
c0108997:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010899a:	83 c0 1c             	add    $0x1c,%eax
c010899d:	c7 44 24 08 20 00 00 	movl   $0x20,0x8(%esp)
c01089a4:	00 
c01089a5:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01089ac:	00 
c01089ad:	89 04 24             	mov    %eax,(%esp)
c01089b0:	e8 2f 15 00 00       	call   c0109ee4 <memset>
        proc->tf = NULL;           // 初始中断陷阱帧指针为NULL
c01089b5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01089b8:	c7 40 3c 00 00 00 00 	movl   $0x0,0x3c(%eax)
        proc->cr3 = boot_cr3;      // 初始CR3寄存器值为0
c01089bf:	8b 15 08 c0 12 c0    	mov    0xc012c008,%edx
c01089c5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01089c8:	89 50 40             	mov    %edx,0x40(%eax)
        proc->flags = 0;           // 初始进程标志为0
c01089cb:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01089ce:	c7 40 44 00 00 00 00 	movl   $0x0,0x44(%eax)
        memset(proc->name, 0, PROC_NAME_LEN);   // 初始进程名称为空字符串
c01089d5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01089d8:	83 c0 48             	add    $0x48,%eax
c01089db:	c7 44 24 08 0f 00 00 	movl   $0xf,0x8(%esp)
c01089e2:	00 
c01089e3:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c01089ea:	00 
c01089eb:	89 04 24             	mov    %eax,(%esp)
c01089ee:	e8 f1 14 00 00       	call   c0109ee4 <memset>
    }
    return proc;
c01089f3:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c01089f6:	89 ec                	mov    %ebp,%esp
c01089f8:	5d                   	pop    %ebp
c01089f9:	c3                   	ret    

c01089fa <set_proc_name>:
 * @return 返回指向进程名称的指针，这是在内存中直接修改后的结果
 * 
 * 注意：此函数直接操作传入的进程结构体，对名称字段进行先清空后赋值的操作
 */
char *
set_proc_name(struct proc_struct *proc, const char *name) {
c01089fa:	55                   	push   %ebp
c01089fb:	89 e5                	mov    %esp,%ebp
c01089fd:	83 ec 18             	sub    $0x18,%esp
    
    // 清空进程名称字段中的现有内容，以准备存储新的名称
    memset(proc->name, 0, sizeof(proc->name));
c0108a00:	8b 45 08             	mov    0x8(%ebp),%eax
c0108a03:	83 c0 48             	add    $0x48,%eax
c0108a06:	c7 44 24 08 10 00 00 	movl   $0x10,0x8(%esp)
c0108a0d:	00 
c0108a0e:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0108a15:	00 
c0108a16:	89 04 24             	mov    %eax,(%esp)
c0108a19:	e8 c6 14 00 00       	call   c0109ee4 <memset>
    // 将新的名称复制到进程名称字段中
    return memcpy(proc->name, name, PROC_NAME_LEN);
c0108a1e:	8b 45 08             	mov    0x8(%ebp),%eax
c0108a21:	8d 50 48             	lea    0x48(%eax),%edx
c0108a24:	c7 44 24 08 0f 00 00 	movl   $0xf,0x8(%esp)
c0108a2b:	00 
c0108a2c:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108a2f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108a33:	89 14 24             	mov    %edx,(%esp)
c0108a36:	e8 8e 15 00 00       	call   c0109fc9 <memcpy>
}
c0108a3b:	89 ec                	mov    %ebp,%esp
c0108a3d:	5d                   	pop    %ebp
c0108a3e:	c3                   	ret    

c0108a3f <get_proc_name>:

// get_proc_name - get the name of proc
char *
get_proc_name(struct proc_struct *proc) {
c0108a3f:	55                   	push   %ebp
c0108a40:	89 e5                	mov    %esp,%ebp
c0108a42:	83 ec 18             	sub    $0x18,%esp
    static char name[PROC_NAME_LEN + 1];
    memset(name, 0, sizeof(name));
c0108a45:	c7 44 24 08 10 00 00 	movl   $0x10,0x8(%esp)
c0108a4c:	00 
c0108a4d:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0108a54:	00 
c0108a55:	c7 04 24 a4 e1 12 c0 	movl   $0xc012e1a4,(%esp)
c0108a5c:	e8 83 14 00 00       	call   c0109ee4 <memset>
    return memcpy(name, proc->name, PROC_NAME_LEN);
c0108a61:	8b 45 08             	mov    0x8(%ebp),%eax
c0108a64:	83 c0 48             	add    $0x48,%eax
c0108a67:	c7 44 24 08 0f 00 00 	movl   $0xf,0x8(%esp)
c0108a6e:	00 
c0108a6f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108a73:	c7 04 24 a4 e1 12 c0 	movl   $0xc012e1a4,(%esp)
c0108a7a:	e8 4a 15 00 00       	call   c0109fc9 <memcpy>
}
c0108a7f:	89 ec                	mov    %ebp,%esp
c0108a81:	5d                   	pop    %ebp
c0108a82:	c3                   	ret    

c0108a83 <get_pid>:
 * 它使用静态变量来跟踪最后一个分配的PID和下一个安全PID，以提高效率并避免PID冲突。
 * 
 * @return 返回一个未被使用的进程ID。
 */
static int
get_pid(void) {
c0108a83:	55                   	push   %ebp
c0108a84:	89 e5                	mov    %esp,%ebp
c0108a86:	83 ec 10             	sub    $0x10,%esp
    static_assert(MAX_PID > MAX_PROCESS);
    
    // 定义一个指向进程结构的指针，用于遍历进程列表。
    struct proc_struct *proc;
    // 初始化列表指针，从进程列表的头部开始。
    list_entry_t *list = &proc_list, *le;
c0108a89:	c7 45 f8 80 c1 12 c0 	movl   $0xc012c180,-0x8(%ebp)
    // 定义静态变量，next_safe用于记录下一个安全的PID值，last_pid用于记录上一个分配的PID。
    static int next_safe = MAX_PID, last_pid = MAX_PID;

    // 尝试递增last_pid以查找下一个可用的PID，如果超过最大值则重置为1。
    if (++ last_pid >= MAX_PID) {
c0108a90:	a1 80 8a 12 c0       	mov    0xc0128a80,%eax
c0108a95:	40                   	inc    %eax
c0108a96:	a3 80 8a 12 c0       	mov    %eax,0xc0128a80
c0108a9b:	a1 80 8a 12 c0       	mov    0xc0128a80,%eax
c0108aa0:	3d ff 1f 00 00       	cmp    $0x1fff,%eax
c0108aa5:	7e 0c                	jle    c0108ab3 <get_pid+0x30>
        last_pid = 1;
c0108aa7:	c7 05 80 8a 12 c0 01 	movl   $0x1,0xc0128a80
c0108aae:	00 00 00 
        goto inside;
c0108ab1:	eb 14                	jmp    c0108ac7 <get_pid+0x44>
    }

     // 如果当前的last_pid大于等于next_safe，表示需要重新计算下一个安全的PID。
    if (last_pid >= next_safe) {
c0108ab3:	8b 15 80 8a 12 c0    	mov    0xc0128a80,%edx
c0108ab9:	a1 84 8a 12 c0       	mov    0xc0128a84,%eax
c0108abe:	39 c2                	cmp    %eax,%edx
c0108ac0:	0f 8c ab 00 00 00    	jl     c0108b71 <get_pid+0xee>
    inside:
c0108ac6:	90                   	nop
        next_safe = MAX_PID;
c0108ac7:	c7 05 84 8a 12 c0 00 	movl   $0x2000,0xc0128a84
c0108ace:	20 00 00 
    repeat:
        // 从进程列表的头部开始遍历。
        le = list;
c0108ad1:	8b 45 f8             	mov    -0x8(%ebp),%eax
c0108ad4:	89 45 fc             	mov    %eax,-0x4(%ebp)
        while ((le = list_next(le)) != list) {
c0108ad7:	eb 7d                	jmp    c0108b56 <get_pid+0xd3>

            // 将列表项转换为进程结构。
            proc = le2proc(le, list_link);
c0108ad9:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0108adc:	83 e8 58             	sub    $0x58,%eax
c0108adf:	89 45 f4             	mov    %eax,-0xc(%ebp)

        // 如果找到相同PID的进程，表示当前last_pid已被使用，需要继续寻找下一个可用的PID。
            if (proc->pid == last_pid) {
c0108ae2:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108ae5:	8b 50 04             	mov    0x4(%eax),%edx
c0108ae8:	a1 80 8a 12 c0       	mov    0xc0128a80,%eax
c0108aed:	39 c2                	cmp    %eax,%edx
c0108aef:	75 3c                	jne    c0108b2d <get_pid+0xaa>
                if (++ last_pid >= next_safe) {
c0108af1:	a1 80 8a 12 c0       	mov    0xc0128a80,%eax
c0108af6:	40                   	inc    %eax
c0108af7:	a3 80 8a 12 c0       	mov    %eax,0xc0128a80
c0108afc:	8b 15 80 8a 12 c0    	mov    0xc0128a80,%edx
c0108b02:	a1 84 8a 12 c0       	mov    0xc0128a84,%eax
c0108b07:	39 c2                	cmp    %eax,%edx
c0108b09:	7c 4b                	jl     c0108b56 <get_pid+0xd3>
                    if (last_pid >= MAX_PID) {
c0108b0b:	a1 80 8a 12 c0       	mov    0xc0128a80,%eax
c0108b10:	3d ff 1f 00 00       	cmp    $0x1fff,%eax
c0108b15:	7e 0a                	jle    c0108b21 <get_pid+0x9e>
                        last_pid = 1;
c0108b17:	c7 05 80 8a 12 c0 01 	movl   $0x1,0xc0128a80
c0108b1e:	00 00 00 
                    }
                    next_safe = MAX_PID;
c0108b21:	c7 05 84 8a 12 c0 00 	movl   $0x2000,0xc0128a84
c0108b28:	20 00 00 
                    goto repeat;
c0108b2b:	eb a4                	jmp    c0108ad1 <get_pid+0x4e>
                }
            }

            // 如果找到一个更大的PID，更新next_safe为当前进程的PID，以确保找到的PID是安全的。
            else if (proc->pid > last_pid && next_safe > proc->pid) {
c0108b2d:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108b30:	8b 50 04             	mov    0x4(%eax),%edx
c0108b33:	a1 80 8a 12 c0       	mov    0xc0128a80,%eax
c0108b38:	39 c2                	cmp    %eax,%edx
c0108b3a:	7e 1a                	jle    c0108b56 <get_pid+0xd3>
c0108b3c:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108b3f:	8b 50 04             	mov    0x4(%eax),%edx
c0108b42:	a1 84 8a 12 c0       	mov    0xc0128a84,%eax
c0108b47:	39 c2                	cmp    %eax,%edx
c0108b49:	7d 0b                	jge    c0108b56 <get_pid+0xd3>
                next_safe = proc->pid;
c0108b4b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108b4e:	8b 40 04             	mov    0x4(%eax),%eax
c0108b51:	a3 84 8a 12 c0       	mov    %eax,0xc0128a84
c0108b56:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0108b59:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108b5c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108b5f:	8b 40 04             	mov    0x4(%eax),%eax
        while ((le = list_next(le)) != list) {
c0108b62:	89 45 fc             	mov    %eax,-0x4(%ebp)
c0108b65:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0108b68:	3b 45 f8             	cmp    -0x8(%ebp),%eax
c0108b6b:	0f 85 68 ff ff ff    	jne    c0108ad9 <get_pid+0x56>
            }
        }
    }
    // 返回找到的可用PID。
    return last_pid;
c0108b71:	a1 80 8a 12 c0       	mov    0xc0128a80,%eax
}
c0108b76:	89 ec                	mov    %ebp,%esp
c0108b78:	5d                   	pop    %ebp
c0108b79:	c3                   	ret    

c0108b7a <proc_run>:

// proc_run - make process "proc" running on cpu
// NOTE: before call switch_to, should load  base addr of "proc"'s new PDT
void
proc_run(struct proc_struct *proc) {
c0108b7a:	55                   	push   %ebp
c0108b7b:	89 e5                	mov    %esp,%ebp
c0108b7d:	83 ec 28             	sub    $0x28,%esp
    if (proc != current) {
c0108b80:	a1 90 c1 12 c0       	mov    0xc012c190,%eax
c0108b85:	39 45 08             	cmp    %eax,0x8(%ebp)
c0108b88:	74 64                	je     c0108bee <proc_run+0x74>
        bool intr_flag;
        struct proc_struct *prev = current, *next = proc;
c0108b8a:	a1 90 c1 12 c0       	mov    0xc012c190,%eax
c0108b8f:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108b92:	8b 45 08             	mov    0x8(%ebp),%eax
c0108b95:	89 45 f0             	mov    %eax,-0x10(%ebp)
        local_intr_save(intr_flag);
c0108b98:	e8 3f fc ff ff       	call   c01087dc <__intr_save>
c0108b9d:	89 45 ec             	mov    %eax,-0x14(%ebp)
        {
            current = proc;
c0108ba0:	8b 45 08             	mov    0x8(%ebp),%eax
c0108ba3:	a3 90 c1 12 c0       	mov    %eax,0xc012c190
            load_esp0(next->kstack + KSTACKSIZE);
c0108ba8:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108bab:	8b 40 0c             	mov    0xc(%eax),%eax
c0108bae:	05 00 20 00 00       	add    $0x2000,%eax
c0108bb3:	89 04 24             	mov    %eax,(%esp)
c0108bb6:	e8 ce c2 ff ff       	call   c0104e89 <load_esp0>
            lcr3(next->cr3);
c0108bbb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108bbe:	8b 40 40             	mov    0x40(%eax),%eax
c0108bc1:	89 45 e8             	mov    %eax,-0x18(%ebp)
    asm volatile ("mov %0, %%cr3" :: "r" (cr3) : "memory");
c0108bc4:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108bc7:	0f 22 d8             	mov    %eax,%cr3
}
c0108bca:	90                   	nop
            switch_to(&(prev->context), &(next->context));
c0108bcb:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108bce:	8d 50 1c             	lea    0x1c(%eax),%edx
c0108bd1:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108bd4:	83 c0 1c             	add    $0x1c,%eax
c0108bd7:	89 54 24 04          	mov    %edx,0x4(%esp)
c0108bdb:	89 04 24             	mov    %eax,(%esp)
c0108bde:	e8 d5 06 00 00       	call   c01092b8 <switch_to>
        }
        local_intr_restore(intr_flag);
c0108be3:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108be6:	89 04 24             	mov    %eax,(%esp)
c0108be9:	e8 1a fc ff ff       	call   c0108808 <__intr_restore>
    }
}
c0108bee:	90                   	nop
c0108bef:	89 ec                	mov    %ebp,%esp
c0108bf1:	5d                   	pop    %ebp
c0108bf2:	c3                   	ret    

c0108bf3 <forkret>:

// forkret -- the first kernel entry point of a new thread/process
// NOTE: the addr of forkret is setted in copy_thread function
//       after switch_to, the current proc will execute here.
static void
forkret(void) {
c0108bf3:	55                   	push   %ebp
c0108bf4:	89 e5                	mov    %esp,%ebp
c0108bf6:	83 ec 18             	sub    $0x18,%esp
    forkrets(current->tf);
c0108bf9:	a1 90 c1 12 c0       	mov    0xc012c190,%eax
c0108bfe:	8b 40 3c             	mov    0x3c(%eax),%eax
c0108c01:	89 04 24             	mov    %eax,(%esp)
c0108c04:	e8 b7 9c ff ff       	call   c01028c0 <forkrets>
}
c0108c09:	90                   	nop
c0108c0a:	89 ec                	mov    %ebp,%esp
c0108c0c:	5d                   	pop    %ebp
c0108c0d:	c3                   	ret    

c0108c0e <hash_proc>:
 * 这有助于在需要时快速查找进程
 * 
 * @param proc 指向进程结构体的指针，表示要添加到哈希表的进程
 */
static void
hash_proc(struct proc_struct *proc) {
c0108c0e:	55                   	push   %ebp
c0108c0f:	89 e5                	mov    %esp,%ebp
c0108c11:	83 ec 38             	sub    $0x38,%esp
c0108c14:	89 5d fc             	mov    %ebx,-0x4(%ebp)
    // 根据进程的PID计算哈希值，并将进程添加到相应哈希链表的末尾
    list_add(hash_list + pid_hashfn(proc->pid), &(proc->hash_link));
c0108c17:	8b 45 08             	mov    0x8(%ebp),%eax
c0108c1a:	8d 58 60             	lea    0x60(%eax),%ebx
c0108c1d:	8b 45 08             	mov    0x8(%ebp),%eax
c0108c20:	8b 40 04             	mov    0x4(%eax),%eax
c0108c23:	c7 44 24 04 0a 00 00 	movl   $0xa,0x4(%esp)
c0108c2a:	00 
c0108c2b:	89 04 24             	mov    %eax,(%esp)
c0108c2e:	e8 14 08 00 00       	call   c0109447 <hash32>
c0108c33:	c1 e0 03             	shl    $0x3,%eax
c0108c36:	05 a0 c1 12 c0       	add    $0xc012c1a0,%eax
c0108c3b:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108c3e:	89 5d f0             	mov    %ebx,-0x10(%ebp)
c0108c41:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108c44:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0108c47:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108c4a:	89 45 e8             	mov    %eax,-0x18(%ebp)
    __list_add(elm, listelm, listelm->next);
c0108c4d:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108c50:	8b 40 04             	mov    0x4(%eax),%eax
c0108c53:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0108c56:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c0108c59:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0108c5c:	89 55 e0             	mov    %edx,-0x20(%ebp)
c0108c5f:	89 45 dc             	mov    %eax,-0x24(%ebp)
    prev->next = next->prev = elm;
c0108c62:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108c65:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0108c68:	89 10                	mov    %edx,(%eax)
c0108c6a:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0108c6d:	8b 10                	mov    (%eax),%edx
c0108c6f:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108c72:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c0108c75:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108c78:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0108c7b:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0108c7e:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108c81:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0108c84:	89 10                	mov    %edx,(%eax)
}
c0108c86:	90                   	nop
}
c0108c87:	90                   	nop
}
c0108c88:	90                   	nop
}
c0108c89:	90                   	nop
c0108c8a:	8b 5d fc             	mov    -0x4(%ebp),%ebx
c0108c8d:	89 ec                	mov    %ebp,%esp
c0108c8f:	5d                   	pop    %ebp
c0108c90:	c3                   	ret    

c0108c91 <find_proc>:

// find_proc - find proc frome proc hash_list according to pid
struct proc_struct *
find_proc(int pid) {
c0108c91:	55                   	push   %ebp
c0108c92:	89 e5                	mov    %esp,%ebp
c0108c94:	83 ec 28             	sub    $0x28,%esp
    if (0 < pid && pid < MAX_PID) {
c0108c97:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0108c9b:	7e 5f                	jle    c0108cfc <find_proc+0x6b>
c0108c9d:	81 7d 08 ff 1f 00 00 	cmpl   $0x1fff,0x8(%ebp)
c0108ca4:	7f 56                	jg     c0108cfc <find_proc+0x6b>
        list_entry_t *list = hash_list + pid_hashfn(pid), *le = list;
c0108ca6:	8b 45 08             	mov    0x8(%ebp),%eax
c0108ca9:	c7 44 24 04 0a 00 00 	movl   $0xa,0x4(%esp)
c0108cb0:	00 
c0108cb1:	89 04 24             	mov    %eax,(%esp)
c0108cb4:	e8 8e 07 00 00       	call   c0109447 <hash32>
c0108cb9:	c1 e0 03             	shl    $0x3,%eax
c0108cbc:	05 a0 c1 12 c0       	add    $0xc012c1a0,%eax
c0108cc1:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108cc4:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108cc7:	89 45 f4             	mov    %eax,-0xc(%ebp)
        while ((le = list_next(le)) != list) {
c0108cca:	eb 19                	jmp    c0108ce5 <find_proc+0x54>
            struct proc_struct *proc = le2proc(le, hash_link);
c0108ccc:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108ccf:	83 e8 60             	sub    $0x60,%eax
c0108cd2:	89 45 ec             	mov    %eax,-0x14(%ebp)
            if (proc->pid == pid) {
c0108cd5:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108cd8:	8b 40 04             	mov    0x4(%eax),%eax
c0108cdb:	39 45 08             	cmp    %eax,0x8(%ebp)
c0108cde:	75 05                	jne    c0108ce5 <find_proc+0x54>
                return proc;
c0108ce0:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0108ce3:	eb 1c                	jmp    c0108d01 <find_proc+0x70>
c0108ce5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108ce8:	89 45 e8             	mov    %eax,-0x18(%ebp)
    return listelm->next;
c0108ceb:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108cee:	8b 40 04             	mov    0x4(%eax),%eax
        while ((le = list_next(le)) != list) {
c0108cf1:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0108cf4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108cf7:	3b 45 f0             	cmp    -0x10(%ebp),%eax
c0108cfa:	75 d0                	jne    c0108ccc <find_proc+0x3b>
            }
        }
    }
    return NULL;
c0108cfc:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0108d01:	89 ec                	mov    %ebp,%esp
c0108d03:	5d                   	pop    %ebp
c0108d04:	c3                   	ret    

c0108d05 <kernel_thread>:
 * 
 * 该函数通过设置trapframe来创建一个内核线程，并安排其执行指定的函数fn
 * 使用do_fork函数来进行实际的线程创建操作，创建的线程将共享父线程的虚拟内存
 */
int
kernel_thread(int (*fn)(void *), void *arg, uint32_t clone_flags) {
c0108d05:	55                   	push   %ebp
c0108d06:	89 e5                	mov    %esp,%ebp
c0108d08:	83 ec 68             	sub    $0x68,%esp
    // 初始化trapframe结构体，用于描述线程的初始状态
    struct trapframe tf;
    memset(&tf, 0, sizeof(struct trapframe));
c0108d0b:	c7 44 24 08 4c 00 00 	movl   $0x4c,0x8(%esp)
c0108d12:	00 
c0108d13:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0108d1a:	00 
c0108d1b:	8d 45 ac             	lea    -0x54(%ebp),%eax
c0108d1e:	89 04 24             	mov    %eax,(%esp)
c0108d21:	e8 be 11 00 00       	call   c0109ee4 <memset>

    // 设置代码段和数据段寄存器的值，使线程运行在内核态
    tf.tf_cs = KERNEL_CS;
c0108d26:	66 c7 45 e8 08 00    	movw   $0x8,-0x18(%ebp)
    tf.tf_ds = tf.tf_es = tf.tf_ss = KERNEL_DS;
c0108d2c:	66 c7 45 f4 10 00    	movw   $0x10,-0xc(%ebp)
c0108d32:	0f b7 45 f4          	movzwl -0xc(%ebp),%eax
c0108d36:	66 89 45 d4          	mov    %ax,-0x2c(%ebp)
c0108d3a:	0f b7 45 d4          	movzwl -0x2c(%ebp),%eax
c0108d3e:	66 89 45 d8          	mov    %ax,-0x28(%ebp)

    // 将要执行的函数fn的地址和参数arg的地址分别放入ebx和edx寄存器
    tf.tf_regs.reg_ebx = (uint32_t)fn;
c0108d42:	8b 45 08             	mov    0x8(%ebp),%eax
c0108d45:	89 45 bc             	mov    %eax,-0x44(%ebp)
    tf.tf_regs.reg_edx = (uint32_t)arg;
c0108d48:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108d4b:	89 45 c0             	mov    %eax,-0x40(%ebp)

    // 设置指令指针寄存器eip，使其指向内核线程入口函数kernel_thread_entry
    tf.tf_eip = (uint32_t)kernel_thread_entry;
c0108d4e:	b8 d3 87 10 c0       	mov    $0xc01087d3,%eax
c0108d53:	89 45 e4             	mov    %eax,-0x1c(%ebp)

    // 调用do_fork函数创建新线程，新线程将共享父线程的虚拟内存
    // 并将新线程的初始状态设置为之前准备的trapframe
    return do_fork(clone_flags | CLONE_VM, 0, &tf);
c0108d56:	8b 45 10             	mov    0x10(%ebp),%eax
c0108d59:	0d 00 01 00 00       	or     $0x100,%eax
c0108d5e:	89 c2                	mov    %eax,%edx
c0108d60:	8d 45 ac             	lea    -0x54(%ebp),%eax
c0108d63:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108d67:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
c0108d6e:	00 
c0108d6f:	89 14 24             	mov    %edx,(%esp)
c0108d72:	e8 90 01 00 00       	call   c0108f07 <do_fork>
}
c0108d77:	89 ec                	mov    %ebp,%esp
c0108d79:	5d                   	pop    %ebp
c0108d7a:	c3                   	ret    

c0108d7b <setup_kstack>:
 * 
 * 此函数通过分配一页内存用作进程的内核栈，并将该内存页的虚拟地址设置为进程的内核栈地址
 * 如果内存分配成功，则返回0；如果内存分配失败，则返回-E_NO_MEM
 */
static int
setup_kstack(struct proc_struct *proc) {
c0108d7b:	55                   	push   %ebp
c0108d7c:	89 e5                	mov    %esp,%ebp
c0108d7e:	83 ec 28             	sub    $0x28,%esp
    // 分配KSTACKPAGE页内存用作内核栈
    struct Page *page = alloc_pages(KSTACKPAGE);
c0108d81:	c7 04 24 02 00 00 00 	movl   $0x2,(%esp)
c0108d88:	e8 4e c2 ff ff       	call   c0104fdb <alloc_pages>
c0108d8d:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (page != NULL) {
c0108d90:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0108d94:	74 1a                	je     c0108db0 <setup_kstack+0x35>
        // 如果内存分配成功，将内存页的虚拟地址设置为进程的内核栈地址
        proc->kstack = (uintptr_t)page2kva(page);
c0108d96:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0108d99:	89 04 24             	mov    %eax,(%esp)
c0108d9c:	e8 f0 fa ff ff       	call   c0108891 <page2kva>
c0108da1:	89 c2                	mov    %eax,%edx
c0108da3:	8b 45 08             	mov    0x8(%ebp),%eax
c0108da6:	89 50 0c             	mov    %edx,0xc(%eax)
        return 0;
c0108da9:	b8 00 00 00 00       	mov    $0x0,%eax
c0108dae:	eb 05                	jmp    c0108db5 <setup_kstack+0x3a>
    }
    // 如果内存分配失败，返回错误码
    return -E_NO_MEM;
c0108db0:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
}
c0108db5:	89 ec                	mov    %ebp,%esp
c0108db7:	5d                   	pop    %ebp
c0108db8:	c3                   	ret    

c0108db9 <put_kstack>:

// put_kstack - free the memory space of process kernel stack
static void
put_kstack(struct proc_struct *proc) {
c0108db9:	55                   	push   %ebp
c0108dba:	89 e5                	mov    %esp,%ebp
c0108dbc:	83 ec 18             	sub    $0x18,%esp
    free_pages(kva2page((void *)(proc->kstack)), KSTACKPAGE);
c0108dbf:	8b 45 08             	mov    0x8(%ebp),%eax
c0108dc2:	8b 40 0c             	mov    0xc(%eax),%eax
c0108dc5:	89 04 24             	mov    %eax,(%esp)
c0108dc8:	e8 1a fb ff ff       	call   c01088e7 <kva2page>
c0108dcd:	c7 44 24 04 02 00 00 	movl   $0x2,0x4(%esp)
c0108dd4:	00 
c0108dd5:	89 04 24             	mov    %eax,(%esp)
c0108dd8:	e8 6b c2 ff ff       	call   c0105048 <free_pages>
}
c0108ddd:	90                   	nop
c0108dde:	89 ec                	mov    %ebp,%esp
c0108de0:	5d                   	pop    %ebp
c0108de1:	c3                   	ret    

c0108de2 <copy_mm>:
 * @param proc 指向新进程的进程结构体指针，用于存储复制的内存管理信息。
 * 
 * 断言当前进程没有内存管理信息。
 */
static int
copy_mm(uint32_t clone_flags, struct proc_struct *proc) {
c0108de2:	55                   	push   %ebp
c0108de3:	89 e5                	mov    %esp,%ebp
c0108de5:	83 ec 18             	sub    $0x18,%esp
    assert(current->mm == NULL);
c0108de8:	a1 90 c1 12 c0       	mov    0xc012c190,%eax
c0108ded:	8b 40 18             	mov    0x18(%eax),%eax
c0108df0:	85 c0                	test   %eax,%eax
c0108df2:	74 24                	je     c0108e18 <copy_mm+0x36>
c0108df4:	c7 44 24 0c 18 c0 10 	movl   $0xc010c018,0xc(%esp)
c0108dfb:	c0 
c0108dfc:	c7 44 24 08 2c c0 10 	movl   $0xc010c02c,0x8(%esp)
c0108e03:	c0 
c0108e04:	c7 44 24 04 5d 01 00 	movl   $0x15d,0x4(%esp)
c0108e0b:	00 
c0108e0c:	c7 04 24 41 c0 10 c0 	movl   $0xc010c041,(%esp)
c0108e13:	e8 2d 7e ff ff       	call   c0100c45 <__panic>
    /* do nothing in this project */
    return 0;
c0108e18:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0108e1d:	89 ec                	mov    %ebp,%esp
c0108e1f:	5d                   	pop    %ebp
c0108e20:	c3                   	ret    

c0108e21 <copy_thread>:
 * @param proc 指向新进程的进程结构体，用于存储初始化后的陷阱帧和上下文信息。
 * @param esp 新进程的栈指针，表示新进程栈的初始位置。
 * @param tf 指向当前线程的陷阱帧结构体，用于将当前线程的执行状态复制到新进程中。
 */
static void
copy_thread(struct proc_struct *proc, uintptr_t esp, struct trapframe *tf) {
c0108e21:	55                   	push   %ebp
c0108e22:	89 e5                	mov    %esp,%ebp
c0108e24:	57                   	push   %edi
c0108e25:	56                   	push   %esi
c0108e26:	53                   	push   %ebx
    // 初始化新进程的陷阱帧，位于其内核栈的顶部
    proc->tf = (struct trapframe *)(proc->kstack + KSTACKSIZE) - 1;
c0108e27:	8b 45 08             	mov    0x8(%ebp),%eax
c0108e2a:	8b 40 0c             	mov    0xc(%eax),%eax
c0108e2d:	05 b4 1f 00 00       	add    $0x1fb4,%eax
c0108e32:	89 c2                	mov    %eax,%edx
c0108e34:	8b 45 08             	mov    0x8(%ebp),%eax
c0108e37:	89 50 3c             	mov    %edx,0x3c(%eax)

    // 将当前线程的陷阱帧内容复制到新进程的陷阱帧
    *(proc->tf) = *tf;
c0108e3a:	8b 45 08             	mov    0x8(%ebp),%eax
c0108e3d:	8b 40 3c             	mov    0x3c(%eax),%eax
c0108e40:	8b 55 10             	mov    0x10(%ebp),%edx
c0108e43:	b9 4c 00 00 00       	mov    $0x4c,%ecx
c0108e48:	89 c3                	mov    %eax,%ebx
c0108e4a:	83 e3 01             	and    $0x1,%ebx
c0108e4d:	85 db                	test   %ebx,%ebx
c0108e4f:	74 0c                	je     c0108e5d <copy_thread+0x3c>
c0108e51:	0f b6 1a             	movzbl (%edx),%ebx
c0108e54:	88 18                	mov    %bl,(%eax)
c0108e56:	8d 40 01             	lea    0x1(%eax),%eax
c0108e59:	8d 52 01             	lea    0x1(%edx),%edx
c0108e5c:	49                   	dec    %ecx
c0108e5d:	89 c3                	mov    %eax,%ebx
c0108e5f:	83 e3 02             	and    $0x2,%ebx
c0108e62:	85 db                	test   %ebx,%ebx
c0108e64:	74 0f                	je     c0108e75 <copy_thread+0x54>
c0108e66:	0f b7 1a             	movzwl (%edx),%ebx
c0108e69:	66 89 18             	mov    %bx,(%eax)
c0108e6c:	8d 40 02             	lea    0x2(%eax),%eax
c0108e6f:	8d 52 02             	lea    0x2(%edx),%edx
c0108e72:	83 e9 02             	sub    $0x2,%ecx
c0108e75:	89 cf                	mov    %ecx,%edi
c0108e77:	83 e7 fc             	and    $0xfffffffc,%edi
c0108e7a:	bb 00 00 00 00       	mov    $0x0,%ebx
c0108e7f:	8b 34 1a             	mov    (%edx,%ebx,1),%esi
c0108e82:	89 34 18             	mov    %esi,(%eax,%ebx,1)
c0108e85:	83 c3 04             	add    $0x4,%ebx
c0108e88:	39 fb                	cmp    %edi,%ebx
c0108e8a:	72 f3                	jb     c0108e7f <copy_thread+0x5e>
c0108e8c:	01 d8                	add    %ebx,%eax
c0108e8e:	01 da                	add    %ebx,%edx
c0108e90:	bb 00 00 00 00       	mov    $0x0,%ebx
c0108e95:	89 ce                	mov    %ecx,%esi
c0108e97:	83 e6 02             	and    $0x2,%esi
c0108e9a:	85 f6                	test   %esi,%esi
c0108e9c:	74 0b                	je     c0108ea9 <copy_thread+0x88>
c0108e9e:	0f b7 34 1a          	movzwl (%edx,%ebx,1),%esi
c0108ea2:	66 89 34 18          	mov    %si,(%eax,%ebx,1)
c0108ea6:	83 c3 02             	add    $0x2,%ebx
c0108ea9:	83 e1 01             	and    $0x1,%ecx
c0108eac:	85 c9                	test   %ecx,%ecx
c0108eae:	74 07                	je     c0108eb7 <copy_thread+0x96>
c0108eb0:	0f b6 14 1a          	movzbl (%edx,%ebx,1),%edx
c0108eb4:	88 14 18             	mov    %dl,(%eax,%ebx,1)

    // 设置子进程的返回值为0，表示fork成功
    proc->tf->tf_regs.reg_eax = 0;
c0108eb7:	8b 45 08             	mov    0x8(%ebp),%eax
c0108eba:	8b 40 3c             	mov    0x3c(%eax),%eax
c0108ebd:	c7 40 1c 00 00 00 00 	movl   $0x0,0x1c(%eax)
    // 设置子进程的栈指针为指定的esp位置
    proc->tf->tf_esp = esp;
c0108ec4:	8b 45 08             	mov    0x8(%ebp),%eax
c0108ec7:	8b 40 3c             	mov    0x3c(%eax),%eax
c0108eca:	8b 55 0c             	mov    0xc(%ebp),%edx
c0108ecd:	89 50 44             	mov    %edx,0x44(%eax)
     // 启用子进程的中断标志
    proc->tf->tf_eflags |= FL_IF;
c0108ed0:	8b 45 08             	mov    0x8(%ebp),%eax
c0108ed3:	8b 40 3c             	mov    0x3c(%eax),%eax
c0108ed6:	8b 50 40             	mov    0x40(%eax),%edx
c0108ed9:	8b 45 08             	mov    0x8(%ebp),%eax
c0108edc:	8b 40 3c             	mov    0x3c(%eax),%eax
c0108edf:	81 ca 00 02 00 00    	or     $0x200,%edx
c0108ee5:	89 50 40             	mov    %edx,0x40(%eax)

    // 设置子进程的初始指令指针为forkret函数的地址
    proc->context.eip = (uintptr_t)forkret;
c0108ee8:	ba f3 8b 10 c0       	mov    $0xc0108bf3,%edx
c0108eed:	8b 45 08             	mov    0x8(%ebp),%eax
c0108ef0:	89 50 1c             	mov    %edx,0x1c(%eax)
    // 设置子进程的栈指针为其陷阱帧的地址
    proc->context.esp = (uintptr_t)(proc->tf);
c0108ef3:	8b 45 08             	mov    0x8(%ebp),%eax
c0108ef6:	8b 40 3c             	mov    0x3c(%eax),%eax
c0108ef9:	89 c2                	mov    %eax,%edx
c0108efb:	8b 45 08             	mov    0x8(%ebp),%eax
c0108efe:	89 50 20             	mov    %edx,0x20(%eax)
}
c0108f01:	90                   	nop
c0108f02:	5b                   	pop    %ebx
c0108f03:	5e                   	pop    %esi
c0108f04:	5f                   	pop    %edi
c0108f05:	5d                   	pop    %ebp
c0108f06:	c3                   	ret    

c0108f07 <do_fork>:
 * @stack:       the parent's user stack pointer. if stack==0, It means to fork a kernel thread.
 * @tf:          the trapframe info, which will be copied to child process's proc->tf
 */

int
do_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {
c0108f07:	55                   	push   %ebp
c0108f08:	89 e5                	mov    %esp,%ebp
c0108f0a:	83 ec 48             	sub    $0x48,%esp
    int ret = -E_NO_FREE_PROC;
c0108f0d:	c7 45 f4 fb ff ff ff 	movl   $0xfffffffb,-0xc(%ebp)
    struct proc_struct *proc;
    if (nr_process >= MAX_PROCESS) {
c0108f14:	a1 a0 e1 12 c0       	mov    0xc012e1a0,%eax
c0108f19:	3d ff 0f 00 00       	cmp    $0xfff,%eax
c0108f1e:	0f 8f 17 01 00 00    	jg     c010903b <do_fork+0x134>
        goto fork_out;
    }
    ret = -E_NO_MEM;
c0108f24:	c7 45 f4 fc ff ff ff 	movl   $0xfffffffc,-0xc(%ebp)
    //    4. call copy_thread to setup tf & context in proc_struct
    //    5. insert proc_struct into hash_list && proc_list
    //    6. call wakeup_proc to make the new child process RUNNABLE
    //    7. set ret vaule using child proc's pid
    //调用alloc_proc，首先获得一块用户信息块
    if((proc = alloc_proc()) == NULL){
c0108f2b:	e8 03 fa ff ff       	call   c0108933 <alloc_proc>
c0108f30:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0108f33:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c0108f37:	0f 84 01 01 00 00    	je     c010903e <do_fork+0x137>
        goto fork_out;
    }

    proc->parent = current;
c0108f3d:	8b 15 90 c1 12 c0    	mov    0xc012c190,%edx
c0108f43:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108f46:	89 50 14             	mov    %edx,0x14(%eax)

    //为进程分配一个内核栈
    ret = setup_kstack(proc);
c0108f49:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108f4c:	89 04 24             	mov    %eax,(%esp)
c0108f4f:	e8 27 fe ff ff       	call   c0108d7b <setup_kstack>
c0108f54:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (ret != 0) {
c0108f57:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0108f5b:	0f 85 f1 00 00 00    	jne    c0109052 <do_fork+0x14b>
        goto bad_fork_cleanup_proc;
    }

    //复制原进程的内存管理信息到新进程
    ret = copy_mm(clone_flags, proc);
c0108f61:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108f64:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108f68:	8b 45 08             	mov    0x8(%ebp),%eax
c0108f6b:	89 04 24             	mov    %eax,(%esp)
c0108f6e:	e8 6f fe ff ff       	call   c0108de2 <copy_mm>
c0108f73:	89 45 f4             	mov    %eax,-0xc(%ebp)
    if (ret != 0) {
c0108f76:	83 7d f4 00          	cmpl   $0x0,-0xc(%ebp)
c0108f7a:	0f 85 c4 00 00 00    	jne    c0109044 <do_fork+0x13d>
        goto bad_fork_cleanup_kstack;
    }

    //复制原进程上下文到新进程
    copy_thread(proc, stack, tf);
c0108f80:	8b 45 10             	mov    0x10(%ebp),%eax
c0108f83:	89 44 24 08          	mov    %eax,0x8(%esp)
c0108f87:	8b 45 0c             	mov    0xc(%ebp),%eax
c0108f8a:	89 44 24 04          	mov    %eax,0x4(%esp)
c0108f8e:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108f91:	89 04 24             	mov    %eax,(%esp)
c0108f94:	e8 88 fe ff ff       	call   c0108e21 <copy_thread>

    bool intr_flag;
    local_intr_save(intr_flag);
c0108f99:	e8 3e f8 ff ff       	call   c01087dc <__intr_save>
c0108f9e:	89 45 ec             	mov    %eax,-0x14(%ebp)
    {
        //为新进程分配一个pid
        proc->pid = get_pid();
c0108fa1:	e8 dd fa ff ff       	call   c0108a83 <get_pid>
c0108fa6:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0108fa9:	89 42 04             	mov    %eax,0x4(%edx)
        //将新进程插入到进程列表
        hash_proc(proc);
c0108fac:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108faf:	89 04 24             	mov    %eax,(%esp)
c0108fb2:	e8 57 fc ff ff       	call   c0108c0e <hash_proc>
        list_add(&proc_list, &(proc->list_link));
c0108fb7:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0108fba:	83 c0 58             	add    $0x58,%eax
c0108fbd:	c7 45 e8 80 c1 12 c0 	movl   $0xc012c180,-0x18(%ebp)
c0108fc4:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0108fc7:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0108fca:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0108fcd:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0108fd0:	89 45 dc             	mov    %eax,-0x24(%ebp)
    __list_add(elm, listelm, listelm->next);
c0108fd3:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0108fd6:	8b 40 04             	mov    0x4(%eax),%eax
c0108fd9:	8b 55 dc             	mov    -0x24(%ebp),%edx
c0108fdc:	89 55 d8             	mov    %edx,-0x28(%ebp)
c0108fdf:	8b 55 e0             	mov    -0x20(%ebp),%edx
c0108fe2:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c0108fe5:	89 45 d0             	mov    %eax,-0x30(%ebp)
    prev->next = next->prev = elm;
c0108fe8:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0108feb:	8b 55 d8             	mov    -0x28(%ebp),%edx
c0108fee:	89 10                	mov    %edx,(%eax)
c0108ff0:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0108ff3:	8b 10                	mov    (%eax),%edx
c0108ff5:	8b 45 d4             	mov    -0x2c(%ebp),%eax
c0108ff8:	89 50 04             	mov    %edx,0x4(%eax)
    elm->next = next;
c0108ffb:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0108ffe:	8b 55 d0             	mov    -0x30(%ebp),%edx
c0109001:	89 50 04             	mov    %edx,0x4(%eax)
    elm->prev = prev;
c0109004:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0109007:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c010900a:	89 10                	mov    %edx,(%eax)
}
c010900c:	90                   	nop
}
c010900d:	90                   	nop
}
c010900e:	90                   	nop
        nr_process ++;
c010900f:	a1 a0 e1 12 c0       	mov    0xc012e1a0,%eax
c0109014:	40                   	inc    %eax
c0109015:	a3 a0 e1 12 c0       	mov    %eax,0xc012e1a0

    }
    local_intr_restore(intr_flag);
c010901a:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010901d:	89 04 24             	mov    %eax,(%esp)
c0109020:	e8 e3 f7 ff ff       	call   c0108808 <__intr_restore>
    wakeup_proc(proc);
c0109025:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109028:	89 04 24             	mov    %eax,(%esp)
c010902b:	e8 01 03 00 00       	call   c0109331 <wakeup_proc>
    ret = proc->pid;
c0109030:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109033:	8b 40 04             	mov    0x4(%eax),%eax
c0109036:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109039:	eb 04                	jmp    c010903f <do_fork+0x138>
        goto fork_out;
c010903b:	90                   	nop
c010903c:	eb 01                	jmp    c010903f <do_fork+0x138>
        goto fork_out;
c010903e:	90                   	nop
fork_out:
    return ret;
c010903f:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109042:	eb 1c                	jmp    c0109060 <do_fork+0x159>
        goto bad_fork_cleanup_kstack;
c0109044:	90                   	nop

bad_fork_cleanup_kstack:
    put_kstack(proc);
c0109045:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109048:	89 04 24             	mov    %eax,(%esp)
c010904b:	e8 69 fd ff ff       	call   c0108db9 <put_kstack>
c0109050:	eb 01                	jmp    c0109053 <do_fork+0x14c>
        goto bad_fork_cleanup_proc;
c0109052:	90                   	nop
bad_fork_cleanup_proc:
    kfree(proc);
c0109053:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109056:	89 04 24             	mov    %eax,(%esp)
c0109059:	e8 09 bb ff ff       	call   c0104b67 <kfree>
    goto fork_out;
c010905e:	eb df                	jmp    c010903f <do_fork+0x138>
}
c0109060:	89 ec                	mov    %ebp,%esp
c0109062:	5d                   	pop    %ebp
c0109063:	c3                   	ret    

c0109064 <do_exit>:
// do_exit - called by sys_exit
//   1. call exit_mmap & put_pgdir & mm_destroy to free the almost all memory space of process
//   2. set process' state as PROC_ZOMBIE, then call wakeup_proc(parent) to ask parent reclaim itself.
//   3. call scheduler to switch to other process
int
do_exit(int error_code) {
c0109064:	55                   	push   %ebp
c0109065:	89 e5                	mov    %esp,%ebp
c0109067:	83 ec 18             	sub    $0x18,%esp
    panic("process exit!!.\n");
c010906a:	c7 44 24 08 55 c0 10 	movl   $0xc010c055,0x8(%esp)
c0109071:	c0 
c0109072:	c7 44 24 04 dd 01 00 	movl   $0x1dd,0x4(%esp)
c0109079:	00 
c010907a:	c7 04 24 41 c0 10 c0 	movl   $0xc010c041,(%esp)
c0109081:	e8 bf 7b ff ff       	call   c0100c45 <__panic>

c0109086 <init_main>:
 * 和初始化参数的内容它不进行任何错误处理或复杂逻辑，主要是为了演示和调试目的
 * 
 * @return 返回0，表示初始化成功没有返回值表示失败，因为这是一个特殊的初始化进程
 */
static int
init_main(void *arg) {
c0109086:	55                   	push   %ebp
c0109087:	89 e5                	mov    %esp,%ebp
c0109089:	83 ec 18             	sub    $0x18,%esp
    // 打印当前进程的pid和名称，用于调试和信息展示
    cprintf("this initproc, pid = %d, name = \"%s\"\n", current->pid, get_proc_name(current));
c010908c:	a1 90 c1 12 c0       	mov    0xc012c190,%eax
c0109091:	89 04 24             	mov    %eax,(%esp)
c0109094:	e8 a6 f9 ff ff       	call   c0108a3f <get_proc_name>
c0109099:	8b 15 90 c1 12 c0    	mov    0xc012c190,%edx
c010909f:	8b 52 04             	mov    0x4(%edx),%edx
c01090a2:	89 44 24 08          	mov    %eax,0x8(%esp)
c01090a6:	89 54 24 04          	mov    %edx,0x4(%esp)
c01090aa:	c7 04 24 68 c0 10 c0 	movl   $0xc010c068,(%esp)
c01090b1:	e8 c2 72 ff ff       	call   c0100378 <cprintf>
    
    // 打印传递给初始化进程的参数，这里假设参数是一个字符串
    cprintf("To U: \"%s\".\n", (const char *)arg);
c01090b6:	8b 45 08             	mov    0x8(%ebp),%eax
c01090b9:	89 44 24 04          	mov    %eax,0x4(%esp)
c01090bd:	c7 04 24 8e c0 10 c0 	movl   $0xc010c08e,(%esp)
c01090c4:	e8 af 72 ff ff       	call   c0100378 <cprintf>
    
    // 打印固定的告别信息，表示初始化进程即将结束
    cprintf("To U: \"en.., Bye, Bye. :)\"\n");
c01090c9:	c7 04 24 9b c0 10 c0 	movl   $0xc010c09b,(%esp)
c01090d0:	e8 a3 72 ff ff       	call   c0100378 <cprintf>
    return 0;
c01090d5:	b8 00 00 00 00       	mov    $0x0,%eax
}
c01090da:	89 ec                	mov    %ebp,%esp
c01090dc:	5d                   	pop    %ebp
c01090dd:	c3                   	ret    

c01090de <proc_init>:
/**
 * proc_init函数是进程管理初始化的核心函数。
 * 它负责初始化进程列表、哈希表、空闲进程、以及创建初始化进程。
 */
void
proc_init(void) {
c01090de:	55                   	push   %ebp
c01090df:	89 e5                	mov    %esp,%ebp
c01090e1:	83 ec 28             	sub    $0x28,%esp
c01090e4:	c7 45 ec 80 c1 12 c0 	movl   $0xc012c180,-0x14(%ebp)
    elm->prev = elm->next = elm;
c01090eb:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01090ee:	8b 55 ec             	mov    -0x14(%ebp),%edx
c01090f1:	89 50 04             	mov    %edx,0x4(%eax)
c01090f4:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01090f7:	8b 50 04             	mov    0x4(%eax),%edx
c01090fa:	8b 45 ec             	mov    -0x14(%ebp),%eax
c01090fd:	89 10                	mov    %edx,(%eax)
}
c01090ff:	90                   	nop

    // 初始化全局进程列表
    list_init(&proc_list);

    // 初始化哈希列表，用于快速查找进程
    for (i = 0; i < HASH_LIST_SIZE; i ++) {
c0109100:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
c0109107:	eb 26                	jmp    c010912f <proc_init+0x51>
        list_init(hash_list + i);
c0109109:	8b 45 f4             	mov    -0xc(%ebp),%eax
c010910c:	c1 e0 03             	shl    $0x3,%eax
c010910f:	05 a0 c1 12 c0       	add    $0xc012c1a0,%eax
c0109114:	89 45 e8             	mov    %eax,-0x18(%ebp)
    elm->prev = elm->next = elm;
c0109117:	8b 45 e8             	mov    -0x18(%ebp),%eax
c010911a:	8b 55 e8             	mov    -0x18(%ebp),%edx
c010911d:	89 50 04             	mov    %edx,0x4(%eax)
c0109120:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109123:	8b 50 04             	mov    0x4(%eax),%edx
c0109126:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109129:	89 10                	mov    %edx,(%eax)
}
c010912b:	90                   	nop
    for (i = 0; i < HASH_LIST_SIZE; i ++) {
c010912c:	ff 45 f4             	incl   -0xc(%ebp)
c010912f:	81 7d f4 ff 03 00 00 	cmpl   $0x3ff,-0xc(%ebp)
c0109136:	7e d1                	jle    c0109109 <proc_init+0x2b>
    }

    // 分配空闲进程idleproc，这是系统中的第一个进程
    if ((idleproc = alloc_proc()) == NULL) {
c0109138:	e8 f6 f7 ff ff       	call   c0108933 <alloc_proc>
c010913d:	a3 88 c1 12 c0       	mov    %eax,0xc012c188
c0109142:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c0109147:	85 c0                	test   %eax,%eax
c0109149:	75 1c                	jne    c0109167 <proc_init+0x89>
        panic("cannot alloc idleproc.\n");
c010914b:	c7 44 24 08 b7 c0 10 	movl   $0xc010c0b7,0x8(%esp)
c0109152:	c0 
c0109153:	c7 44 24 04 0c 02 00 	movl   $0x20c,0x4(%esp)
c010915a:	00 
c010915b:	c7 04 24 41 c0 10 c0 	movl   $0xc010c041,(%esp)
c0109162:	e8 de 7a ff ff       	call   c0100c45 <__panic>
    }

    // 设置idleproc的基本信息
    idleproc->pid = 0;
c0109167:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c010916c:	c7 40 04 00 00 00 00 	movl   $0x0,0x4(%eax)
    idleproc->state = PROC_RUNNABLE;
c0109173:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c0109178:	c7 00 02 00 00 00    	movl   $0x2,(%eax)
    idleproc->kstack = (uintptr_t)bootstack;
c010917e:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c0109183:	ba 00 60 12 c0       	mov    $0xc0126000,%edx
c0109188:	89 50 0c             	mov    %edx,0xc(%eax)
    idleproc->need_resched = 1;
c010918b:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c0109190:	c7 40 10 01 00 00 00 	movl   $0x1,0x10(%eax)
    set_proc_name(idleproc, "idle");
c0109197:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c010919c:	c7 44 24 04 cf c0 10 	movl   $0xc010c0cf,0x4(%esp)
c01091a3:	c0 
c01091a4:	89 04 24             	mov    %eax,(%esp)
c01091a7:	e8 4e f8 ff ff       	call   c01089fa <set_proc_name>
    nr_process ++;
c01091ac:	a1 a0 e1 12 c0       	mov    0xc012e1a0,%eax
c01091b1:	40                   	inc    %eax
c01091b2:	a3 a0 e1 12 c0       	mov    %eax,0xc012e1a0

    // 将当前进程设置为idleproc
    current = idleproc;
c01091b7:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c01091bc:	a3 90 c1 12 c0       	mov    %eax,0xc012c190

    // 创建初始化进程init_main，这是系统中的第二个进程
    int pid = kernel_thread(init_main, "Hello world!!", 0);
c01091c1:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
c01091c8:	00 
c01091c9:	c7 44 24 04 d4 c0 10 	movl   $0xc010c0d4,0x4(%esp)
c01091d0:	c0 
c01091d1:	c7 04 24 86 90 10 c0 	movl   $0xc0109086,(%esp)
c01091d8:	e8 28 fb ff ff       	call   c0108d05 <kernel_thread>
c01091dd:	89 45 f0             	mov    %eax,-0x10(%ebp)
    if (pid <= 0) {
c01091e0:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01091e4:	7f 1c                	jg     c0109202 <proc_init+0x124>
        panic("create init_main failed.\n");
c01091e6:	c7 44 24 08 e2 c0 10 	movl   $0xc010c0e2,0x8(%esp)
c01091ed:	c0 
c01091ee:	c7 44 24 04 1d 02 00 	movl   $0x21d,0x4(%esp)
c01091f5:	00 
c01091f6:	c7 04 24 41 c0 10 c0 	movl   $0xc010c041,(%esp)
c01091fd:	e8 43 7a ff ff       	call   c0100c45 <__panic>
    }

    // 查找并设置初始化进程initproc
    initproc = find_proc(pid);
c0109202:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109205:	89 04 24             	mov    %eax,(%esp)
c0109208:	e8 84 fa ff ff       	call   c0108c91 <find_proc>
c010920d:	a3 8c c1 12 c0       	mov    %eax,0xc012c18c
    set_proc_name(initproc, "init");
c0109212:	a1 8c c1 12 c0       	mov    0xc012c18c,%eax
c0109217:	c7 44 24 04 fc c0 10 	movl   $0xc010c0fc,0x4(%esp)
c010921e:	c0 
c010921f:	89 04 24             	mov    %eax,(%esp)
c0109222:	e8 d3 f7 ff ff       	call   c01089fa <set_proc_name>

    // 断言确保idleproc和initproc正确初始化
    assert(idleproc != NULL && idleproc->pid == 0);
c0109227:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c010922c:	85 c0                	test   %eax,%eax
c010922e:	74 0c                	je     c010923c <proc_init+0x15e>
c0109230:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c0109235:	8b 40 04             	mov    0x4(%eax),%eax
c0109238:	85 c0                	test   %eax,%eax
c010923a:	74 24                	je     c0109260 <proc_init+0x182>
c010923c:	c7 44 24 0c 04 c1 10 	movl   $0xc010c104,0xc(%esp)
c0109243:	c0 
c0109244:	c7 44 24 08 2c c0 10 	movl   $0xc010c02c,0x8(%esp)
c010924b:	c0 
c010924c:	c7 44 24 04 25 02 00 	movl   $0x225,0x4(%esp)
c0109253:	00 
c0109254:	c7 04 24 41 c0 10 c0 	movl   $0xc010c041,(%esp)
c010925b:	e8 e5 79 ff ff       	call   c0100c45 <__panic>
    assert(initproc != NULL && initproc->pid == 1);
c0109260:	a1 8c c1 12 c0       	mov    0xc012c18c,%eax
c0109265:	85 c0                	test   %eax,%eax
c0109267:	74 0d                	je     c0109276 <proc_init+0x198>
c0109269:	a1 8c c1 12 c0       	mov    0xc012c18c,%eax
c010926e:	8b 40 04             	mov    0x4(%eax),%eax
c0109271:	83 f8 01             	cmp    $0x1,%eax
c0109274:	74 24                	je     c010929a <proc_init+0x1bc>
c0109276:	c7 44 24 0c 2c c1 10 	movl   $0xc010c12c,0xc(%esp)
c010927d:	c0 
c010927e:	c7 44 24 08 2c c0 10 	movl   $0xc010c02c,0x8(%esp)
c0109285:	c0 
c0109286:	c7 44 24 04 26 02 00 	movl   $0x226,0x4(%esp)
c010928d:	00 
c010928e:	c7 04 24 41 c0 10 c0 	movl   $0xc010c041,(%esp)
c0109295:	e8 ab 79 ff ff       	call   c0100c45 <__panic>
}
c010929a:	90                   	nop
c010929b:	89 ec                	mov    %ebp,%esp
c010929d:	5d                   	pop    %ebp
c010929e:	c3                   	ret    

c010929f <cpu_idle>:

// cpu_idle - at the end of kern_init, the first kernel thread idleproc will do below works
void
cpu_idle(void) {
c010929f:	55                   	push   %ebp
c01092a0:	89 e5                	mov    %esp,%ebp
c01092a2:	83 ec 08             	sub    $0x8,%esp
    while (1) {
        //检查当前进程是否需要重新调度
        if (current->need_resched) {
c01092a5:	a1 90 c1 12 c0       	mov    0xc012c190,%eax
c01092aa:	8b 40 10             	mov    0x10(%eax),%eax
c01092ad:	85 c0                	test   %eax,%eax
c01092af:	74 f4                	je     c01092a5 <cpu_idle+0x6>
            schedule();
c01092b1:	e8 c7 00 00 00       	call   c010937d <schedule>
        if (current->need_resched) {
c01092b6:	eb ed                	jmp    c01092a5 <cpu_idle+0x6>

c01092b8 <switch_to>:
.text
.globl switch_to
switch_to:                      # switch_to(from, to)

    # save from's registers
    movl 4(%esp), %eax          # eax points to from
c01092b8:	8b 44 24 04          	mov    0x4(%esp),%eax
    popl 0(%eax)                # save eip !popl
c01092bc:	8f 00                	pop    (%eax)
    movl %esp, 4(%eax)          # save esp::context of from
c01092be:	89 60 04             	mov    %esp,0x4(%eax)
    movl %ebx, 8(%eax)          # save ebx::context of from
c01092c1:	89 58 08             	mov    %ebx,0x8(%eax)
    movl %ecx, 12(%eax)         # save ecx::context of from
c01092c4:	89 48 0c             	mov    %ecx,0xc(%eax)
    movl %edx, 16(%eax)         # save edx::context of from
c01092c7:	89 50 10             	mov    %edx,0x10(%eax)
    movl %esi, 20(%eax)         # save esi::context of from
c01092ca:	89 70 14             	mov    %esi,0x14(%eax)
    movl %edi, 24(%eax)         # save edi::context of from
c01092cd:	89 78 18             	mov    %edi,0x18(%eax)
    movl %ebp, 28(%eax)         # save ebp::context of from
c01092d0:	89 68 1c             	mov    %ebp,0x1c(%eax)

    # restore to's registers
    movl 4(%esp), %eax          # not 8(%esp): popped return address already
c01092d3:	8b 44 24 04          	mov    0x4(%esp),%eax
                                # eax now points to to
    movl 28(%eax), %ebp         # restore ebp::context of to
c01092d7:	8b 68 1c             	mov    0x1c(%eax),%ebp
    movl 24(%eax), %edi         # restore edi::context of to
c01092da:	8b 78 18             	mov    0x18(%eax),%edi
    movl 20(%eax), %esi         # restore esi::context of to
c01092dd:	8b 70 14             	mov    0x14(%eax),%esi
    movl 16(%eax), %edx         # restore edx::context of to
c01092e0:	8b 50 10             	mov    0x10(%eax),%edx
    movl 12(%eax), %ecx         # restore ecx::context of to
c01092e3:	8b 48 0c             	mov    0xc(%eax),%ecx
    movl 8(%eax), %ebx          # restore ebx::context of to
c01092e6:	8b 58 08             	mov    0x8(%eax),%ebx
    movl 4(%eax), %esp          # restore esp::context of to
c01092e9:	8b 60 04             	mov    0x4(%eax),%esp

    pushl 0(%eax)               # push eip
c01092ec:	ff 30                	push   (%eax)

    ret
c01092ee:	c3                   	ret    

c01092ef <__intr_save>:
__intr_save(void) {
c01092ef:	55                   	push   %ebp
c01092f0:	89 e5                	mov    %esp,%ebp
c01092f2:	83 ec 18             	sub    $0x18,%esp
    asm volatile ("pushfl; popl %0" : "=r" (eflags));
c01092f5:	9c                   	pushf  
c01092f6:	58                   	pop    %eax
c01092f7:	89 45 f4             	mov    %eax,-0xc(%ebp)
    return eflags;
c01092fa:	8b 45 f4             	mov    -0xc(%ebp),%eax
    if (read_eflags() & FL_IF) {
c01092fd:	25 00 02 00 00       	and    $0x200,%eax
c0109302:	85 c0                	test   %eax,%eax
c0109304:	74 0c                	je     c0109312 <__intr_save+0x23>
        intr_disable();
c0109306:	e8 f0 8b ff ff       	call   c0101efb <intr_disable>
        return 1;
c010930b:	b8 01 00 00 00       	mov    $0x1,%eax
c0109310:	eb 05                	jmp    c0109317 <__intr_save+0x28>
    return 0;
c0109312:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0109317:	89 ec                	mov    %ebp,%esp
c0109319:	5d                   	pop    %ebp
c010931a:	c3                   	ret    

c010931b <__intr_restore>:
__intr_restore(bool flag) {
c010931b:	55                   	push   %ebp
c010931c:	89 e5                	mov    %esp,%ebp
c010931e:	83 ec 08             	sub    $0x8,%esp
    if (flag) {
c0109321:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0109325:	74 05                	je     c010932c <__intr_restore+0x11>
        intr_enable();
c0109327:	e8 c7 8b ff ff       	call   c0101ef3 <intr_enable>
}
c010932c:	90                   	nop
c010932d:	89 ec                	mov    %ebp,%esp
c010932f:	5d                   	pop    %ebp
c0109330:	c3                   	ret    

c0109331 <wakeup_proc>:
#include <proc.h>
#include <sched.h>
#include <assert.h>

void
wakeup_proc(struct proc_struct *proc) {
c0109331:	55                   	push   %ebp
c0109332:	89 e5                	mov    %esp,%ebp
c0109334:	83 ec 18             	sub    $0x18,%esp
    assert(proc->state != PROC_ZOMBIE && proc->state != PROC_RUNNABLE);
c0109337:	8b 45 08             	mov    0x8(%ebp),%eax
c010933a:	8b 00                	mov    (%eax),%eax
c010933c:	83 f8 03             	cmp    $0x3,%eax
c010933f:	74 0a                	je     c010934b <wakeup_proc+0x1a>
c0109341:	8b 45 08             	mov    0x8(%ebp),%eax
c0109344:	8b 00                	mov    (%eax),%eax
c0109346:	83 f8 02             	cmp    $0x2,%eax
c0109349:	75 24                	jne    c010936f <wakeup_proc+0x3e>
c010934b:	c7 44 24 0c 54 c1 10 	movl   $0xc010c154,0xc(%esp)
c0109352:	c0 
c0109353:	c7 44 24 08 8f c1 10 	movl   $0xc010c18f,0x8(%esp)
c010935a:	c0 
c010935b:	c7 44 24 04 09 00 00 	movl   $0x9,0x4(%esp)
c0109362:	00 
c0109363:	c7 04 24 a4 c1 10 c0 	movl   $0xc010c1a4,(%esp)
c010936a:	e8 d6 78 ff ff       	call   c0100c45 <__panic>
    proc->state = PROC_RUNNABLE;
c010936f:	8b 45 08             	mov    0x8(%ebp),%eax
c0109372:	c7 00 02 00 00 00    	movl   $0x2,(%eax)
}
c0109378:	90                   	nop
c0109379:	89 ec                	mov    %ebp,%esp
c010937b:	5d                   	pop    %ebp
c010937c:	c3                   	ret    

c010937d <schedule>:
 * 如果找到可运行的进程，则选择该进程作为下一个要执行的进程，并进行上下文切换。
 * 如果没有找到可运行的进程，则选择空闲进程作为下一个要执行的进程。
 * 最后，恢复中断状态并退出调度函数。
 */
void
schedule(void) {
c010937d:	55                   	push   %ebp
c010937e:	89 e5                	mov    %esp,%ebp
c0109380:	83 ec 38             	sub    $0x38,%esp
    // 保存中断状态标志
    bool intr_flag;
    // 定义指向进程列表项的指针
    list_entry_t *le, *last;
    // 定义下一个要执行的进程指针，并初始化为NULL
    struct proc_struct *next = NULL;
c0109383:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
    // 保存当前中断状态，并禁止中断
    local_intr_save(intr_flag);
c010938a:	e8 60 ff ff ff       	call   c01092ef <__intr_save>
c010938f:	89 45 ec             	mov    %eax,-0x14(%ebp)
    {
        // 标记当前进程不需要重新调度
        current->need_resched = 0;
c0109392:	a1 90 c1 12 c0       	mov    0xc012c190,%eax
c0109397:	c7 40 10 00 00 00 00 	movl   $0x0,0x10(%eax)
         // 确定进程列表的最后一个元素
        last = (current == idleproc) ? &proc_list : &(current->list_link);
c010939e:	8b 15 90 c1 12 c0    	mov    0xc012c190,%edx
c01093a4:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c01093a9:	39 c2                	cmp    %eax,%edx
c01093ab:	74 0a                	je     c01093b7 <schedule+0x3a>
c01093ad:	a1 90 c1 12 c0       	mov    0xc012c190,%eax
c01093b2:	83 c0 58             	add    $0x58,%eax
c01093b5:	eb 05                	jmp    c01093bc <schedule+0x3f>
c01093b7:	b8 80 c1 12 c0       	mov    $0xc012c180,%eax
c01093bc:	89 45 e8             	mov    %eax,-0x18(%ebp)
         // 从最后一个元素开始遍历进程列表
        le = last;
c01093bf:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01093c2:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01093c5:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01093c8:	89 45 e4             	mov    %eax,-0x1c(%ebp)
    return listelm->next;
c01093cb:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01093ce:	8b 40 04             	mov    0x4(%eax),%eax
        do {
            // 如果不是进程列表的末尾，则继续查找下一个可运行的进程
            if ((le = list_next(le)) != &proc_list) {
c01093d1:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01093d4:	81 7d f4 80 c1 12 c0 	cmpl   $0xc012c180,-0xc(%ebp)
c01093db:	74 13                	je     c01093f0 <schedule+0x73>
                 // 获取当前列表项对应的进程结构体
                next = le2proc(le, list_link);
c01093dd:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01093e0:	83 e8 58             	sub    $0x58,%eax
c01093e3:	89 45 f0             	mov    %eax,-0x10(%ebp)
                // 如果进程处于可运行状态，则停止查找
                if (next->state == PROC_RUNNABLE) {
c01093e6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01093e9:	8b 00                	mov    (%eax),%eax
c01093eb:	83 f8 02             	cmp    $0x2,%eax
c01093ee:	74 0a                	je     c01093fa <schedule+0x7d>
                    break;
                }
            }
        } while (le != last);
c01093f0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c01093f3:	3b 45 e8             	cmp    -0x18(%ebp),%eax
c01093f6:	75 cd                	jne    c01093c5 <schedule+0x48>
c01093f8:	eb 01                	jmp    c01093fb <schedule+0x7e>
                    break;
c01093fa:	90                   	nop
         // 如果没有找到可运行的进程，则选择空闲进程作为下一个要执行的进程
        if (next == NULL || next->state != PROC_RUNNABLE) {
c01093fb:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01093ff:	74 0a                	je     c010940b <schedule+0x8e>
c0109401:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109404:	8b 00                	mov    (%eax),%eax
c0109406:	83 f8 02             	cmp    $0x2,%eax
c0109409:	74 08                	je     c0109413 <schedule+0x96>
            next = idleproc;
c010940b:	a1 88 c1 12 c0       	mov    0xc012c188,%eax
c0109410:	89 45 f0             	mov    %eax,-0x10(%ebp)
        }
         // 增加下一个要执行的进程的运行次数
        next->runs ++;
c0109413:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109416:	8b 40 08             	mov    0x8(%eax),%eax
c0109419:	8d 50 01             	lea    0x1(%eax),%edx
c010941c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010941f:	89 50 08             	mov    %edx,0x8(%eax)
        // 如果下一个要执行的进程不是当前进程，则进行上下文切换
        if (next != current) {
c0109422:	a1 90 c1 12 c0       	mov    0xc012c190,%eax
c0109427:	39 45 f0             	cmp    %eax,-0x10(%ebp)
c010942a:	74 0b                	je     c0109437 <schedule+0xba>
            proc_run(next);
c010942c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c010942f:	89 04 24             	mov    %eax,(%esp)
c0109432:	e8 43 f7 ff ff       	call   c0108b7a <proc_run>
        }
    }
     // 恢复中断状态
    local_intr_restore(intr_flag);
c0109437:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010943a:	89 04 24             	mov    %eax,(%esp)
c010943d:	e8 d9 fe ff ff       	call   c010931b <__intr_restore>
}
c0109442:	90                   	nop
c0109443:	89 ec                	mov    %ebp,%esp
c0109445:	5d                   	pop    %ebp
c0109446:	c3                   	ret    

c0109447 <hash32>:
 * @bits:   the number of bits in a return value
 *
 * High bits are more random, so we use them.
 * */
uint32_t
hash32(uint32_t val, unsigned int bits) {
c0109447:	55                   	push   %ebp
c0109448:	89 e5                	mov    %esp,%ebp
c010944a:	83 ec 10             	sub    $0x10,%esp
    uint32_t hash = val * GOLDEN_RATIO_PRIME_32;
c010944d:	8b 45 08             	mov    0x8(%ebp),%eax
c0109450:	69 c0 01 00 37 9e    	imul   $0x9e370001,%eax,%eax
c0109456:	89 45 fc             	mov    %eax,-0x4(%ebp)
    return (hash >> (32 - bits));
c0109459:	b8 20 00 00 00       	mov    $0x20,%eax
c010945e:	2b 45 0c             	sub    0xc(%ebp),%eax
c0109461:	8b 55 fc             	mov    -0x4(%ebp),%edx
c0109464:	88 c1                	mov    %al,%cl
c0109466:	d3 ea                	shr    %cl,%edx
c0109468:	89 d0                	mov    %edx,%eax
}
c010946a:	89 ec                	mov    %ebp,%esp
c010946c:	5d                   	pop    %ebp
c010946d:	c3                   	ret    

c010946e <printnum>:
 * @width:      maximum number of digits, if the actual width is less than @width, use @padc instead
 * @padc:       character that padded on the left if the actual width is less than @width
 * */
static void
printnum(void (*putch)(int, void*), void *putdat,
        unsigned long long num, unsigned base, int width, int padc) {
c010946e:	55                   	push   %ebp
c010946f:	89 e5                	mov    %esp,%ebp
c0109471:	83 ec 58             	sub    $0x58,%esp
c0109474:	8b 45 10             	mov    0x10(%ebp),%eax
c0109477:	89 45 d0             	mov    %eax,-0x30(%ebp)
c010947a:	8b 45 14             	mov    0x14(%ebp),%eax
c010947d:	89 45 d4             	mov    %eax,-0x2c(%ebp)
    unsigned long long result = num;
c0109480:	8b 45 d0             	mov    -0x30(%ebp),%eax
c0109483:	8b 55 d4             	mov    -0x2c(%ebp),%edx
c0109486:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0109489:	89 55 ec             	mov    %edx,-0x14(%ebp)
    unsigned mod = do_div(result, base);
c010948c:	8b 45 18             	mov    0x18(%ebp),%eax
c010948f:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0109492:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109495:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0109498:	89 45 e0             	mov    %eax,-0x20(%ebp)
c010949b:	89 55 f0             	mov    %edx,-0x10(%ebp)
c010949e:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01094a1:	89 45 f4             	mov    %eax,-0xc(%ebp)
c01094a4:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
c01094a8:	74 1c                	je     c01094c6 <printnum+0x58>
c01094aa:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01094ad:	ba 00 00 00 00       	mov    $0x0,%edx
c01094b2:	f7 75 e4             	divl   -0x1c(%ebp)
c01094b5:	89 55 f4             	mov    %edx,-0xc(%ebp)
c01094b8:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01094bb:	ba 00 00 00 00       	mov    $0x0,%edx
c01094c0:	f7 75 e4             	divl   -0x1c(%ebp)
c01094c3:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01094c6:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01094c9:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01094cc:	f7 75 e4             	divl   -0x1c(%ebp)
c01094cf:	89 45 e0             	mov    %eax,-0x20(%ebp)
c01094d2:	89 55 dc             	mov    %edx,-0x24(%ebp)
c01094d5:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01094d8:	8b 55 f0             	mov    -0x10(%ebp),%edx
c01094db:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01094de:	89 55 ec             	mov    %edx,-0x14(%ebp)
c01094e1:	8b 45 dc             	mov    -0x24(%ebp),%eax
c01094e4:	89 45 d8             	mov    %eax,-0x28(%ebp)

    // first recursively print all preceding (more significant) digits
    if (num >= base) {
c01094e7:	8b 45 18             	mov    0x18(%ebp),%eax
c01094ea:	ba 00 00 00 00       	mov    $0x0,%edx
c01094ef:	8b 4d d4             	mov    -0x2c(%ebp),%ecx
c01094f2:	39 45 d0             	cmp    %eax,-0x30(%ebp)
c01094f5:	19 d1                	sbb    %edx,%ecx
c01094f7:	72 4c                	jb     c0109545 <printnum+0xd7>
        printnum(putch, putdat, result, base, width - 1, padc);
c01094f9:	8b 45 1c             	mov    0x1c(%ebp),%eax
c01094fc:	8d 50 ff             	lea    -0x1(%eax),%edx
c01094ff:	8b 45 20             	mov    0x20(%ebp),%eax
c0109502:	89 44 24 18          	mov    %eax,0x18(%esp)
c0109506:	89 54 24 14          	mov    %edx,0x14(%esp)
c010950a:	8b 45 18             	mov    0x18(%ebp),%eax
c010950d:	89 44 24 10          	mov    %eax,0x10(%esp)
c0109511:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109514:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0109517:	89 44 24 08          	mov    %eax,0x8(%esp)
c010951b:	89 54 24 0c          	mov    %edx,0xc(%esp)
c010951f:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109522:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109526:	8b 45 08             	mov    0x8(%ebp),%eax
c0109529:	89 04 24             	mov    %eax,(%esp)
c010952c:	e8 3d ff ff ff       	call   c010946e <printnum>
c0109531:	eb 1b                	jmp    c010954e <printnum+0xe0>
    } else {
        // print any needed pad characters before first digit
        while (-- width > 0)
            putch(padc, putdat);
c0109533:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109536:	89 44 24 04          	mov    %eax,0x4(%esp)
c010953a:	8b 45 20             	mov    0x20(%ebp),%eax
c010953d:	89 04 24             	mov    %eax,(%esp)
c0109540:	8b 45 08             	mov    0x8(%ebp),%eax
c0109543:	ff d0                	call   *%eax
        while (-- width > 0)
c0109545:	ff 4d 1c             	decl   0x1c(%ebp)
c0109548:	83 7d 1c 00          	cmpl   $0x0,0x1c(%ebp)
c010954c:	7f e5                	jg     c0109533 <printnum+0xc5>
    }
    // then print this (the least significant) digit
    putch("0123456789abcdef"[mod], putdat);
c010954e:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0109551:	05 3c c2 10 c0       	add    $0xc010c23c,%eax
c0109556:	0f b6 00             	movzbl (%eax),%eax
c0109559:	0f be c0             	movsbl %al,%eax
c010955c:	8b 55 0c             	mov    0xc(%ebp),%edx
c010955f:	89 54 24 04          	mov    %edx,0x4(%esp)
c0109563:	89 04 24             	mov    %eax,(%esp)
c0109566:	8b 45 08             	mov    0x8(%ebp),%eax
c0109569:	ff d0                	call   *%eax
}
c010956b:	90                   	nop
c010956c:	89 ec                	mov    %ebp,%esp
c010956e:	5d                   	pop    %ebp
c010956f:	c3                   	ret    

c0109570 <getuint>:
 * getuint - get an unsigned int of various possible sizes from a varargs list
 * @ap:         a varargs list pointer
 * @lflag:      determines the size of the vararg that @ap points to
 * */
static unsigned long long
getuint(va_list *ap, int lflag) {
c0109570:	55                   	push   %ebp
c0109571:	89 e5                	mov    %esp,%ebp
    if (lflag >= 2) {
c0109573:	83 7d 0c 01          	cmpl   $0x1,0xc(%ebp)
c0109577:	7e 14                	jle    c010958d <getuint+0x1d>
        return va_arg(*ap, unsigned long long);
c0109579:	8b 45 08             	mov    0x8(%ebp),%eax
c010957c:	8b 00                	mov    (%eax),%eax
c010957e:	8d 48 08             	lea    0x8(%eax),%ecx
c0109581:	8b 55 08             	mov    0x8(%ebp),%edx
c0109584:	89 0a                	mov    %ecx,(%edx)
c0109586:	8b 50 04             	mov    0x4(%eax),%edx
c0109589:	8b 00                	mov    (%eax),%eax
c010958b:	eb 30                	jmp    c01095bd <getuint+0x4d>
    }
    else if (lflag) {
c010958d:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c0109591:	74 16                	je     c01095a9 <getuint+0x39>
        return va_arg(*ap, unsigned long);
c0109593:	8b 45 08             	mov    0x8(%ebp),%eax
c0109596:	8b 00                	mov    (%eax),%eax
c0109598:	8d 48 04             	lea    0x4(%eax),%ecx
c010959b:	8b 55 08             	mov    0x8(%ebp),%edx
c010959e:	89 0a                	mov    %ecx,(%edx)
c01095a0:	8b 00                	mov    (%eax),%eax
c01095a2:	ba 00 00 00 00       	mov    $0x0,%edx
c01095a7:	eb 14                	jmp    c01095bd <getuint+0x4d>
    }
    else {
        return va_arg(*ap, unsigned int);
c01095a9:	8b 45 08             	mov    0x8(%ebp),%eax
c01095ac:	8b 00                	mov    (%eax),%eax
c01095ae:	8d 48 04             	lea    0x4(%eax),%ecx
c01095b1:	8b 55 08             	mov    0x8(%ebp),%edx
c01095b4:	89 0a                	mov    %ecx,(%edx)
c01095b6:	8b 00                	mov    (%eax),%eax
c01095b8:	ba 00 00 00 00       	mov    $0x0,%edx
    }
}
c01095bd:	5d                   	pop    %ebp
c01095be:	c3                   	ret    

c01095bf <getint>:
 * getint - same as getuint but signed, we can't use getuint because of sign extension
 * @ap:         a varargs list pointer
 * @lflag:      determines the size of the vararg that @ap points to
 * */
static long long
getint(va_list *ap, int lflag) {
c01095bf:	55                   	push   %ebp
c01095c0:	89 e5                	mov    %esp,%ebp
    if (lflag >= 2) {
c01095c2:	83 7d 0c 01          	cmpl   $0x1,0xc(%ebp)
c01095c6:	7e 14                	jle    c01095dc <getint+0x1d>
        return va_arg(*ap, long long);
c01095c8:	8b 45 08             	mov    0x8(%ebp),%eax
c01095cb:	8b 00                	mov    (%eax),%eax
c01095cd:	8d 48 08             	lea    0x8(%eax),%ecx
c01095d0:	8b 55 08             	mov    0x8(%ebp),%edx
c01095d3:	89 0a                	mov    %ecx,(%edx)
c01095d5:	8b 50 04             	mov    0x4(%eax),%edx
c01095d8:	8b 00                	mov    (%eax),%eax
c01095da:	eb 28                	jmp    c0109604 <getint+0x45>
    }
    else if (lflag) {
c01095dc:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c01095e0:	74 12                	je     c01095f4 <getint+0x35>
        return va_arg(*ap, long);
c01095e2:	8b 45 08             	mov    0x8(%ebp),%eax
c01095e5:	8b 00                	mov    (%eax),%eax
c01095e7:	8d 48 04             	lea    0x4(%eax),%ecx
c01095ea:	8b 55 08             	mov    0x8(%ebp),%edx
c01095ed:	89 0a                	mov    %ecx,(%edx)
c01095ef:	8b 00                	mov    (%eax),%eax
c01095f1:	99                   	cltd   
c01095f2:	eb 10                	jmp    c0109604 <getint+0x45>
    }
    else {
        return va_arg(*ap, int);
c01095f4:	8b 45 08             	mov    0x8(%ebp),%eax
c01095f7:	8b 00                	mov    (%eax),%eax
c01095f9:	8d 48 04             	lea    0x4(%eax),%ecx
c01095fc:	8b 55 08             	mov    0x8(%ebp),%edx
c01095ff:	89 0a                	mov    %ecx,(%edx)
c0109601:	8b 00                	mov    (%eax),%eax
c0109603:	99                   	cltd   
    }
}
c0109604:	5d                   	pop    %ebp
c0109605:	c3                   	ret    

c0109606 <printfmt>:
 * @putch:      specified putch function, print a single character
 * @putdat:     used by @putch function
 * @fmt:        the format string to use
 * */
void
printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) {
c0109606:	55                   	push   %ebp
c0109607:	89 e5                	mov    %esp,%ebp
c0109609:	83 ec 28             	sub    $0x28,%esp
    va_list ap;

    va_start(ap, fmt);
c010960c:	8d 45 14             	lea    0x14(%ebp),%eax
c010960f:	89 45 f4             	mov    %eax,-0xc(%ebp)
    vprintfmt(putch, putdat, fmt, ap);
c0109612:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109615:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0109619:	8b 45 10             	mov    0x10(%ebp),%eax
c010961c:	89 44 24 08          	mov    %eax,0x8(%esp)
c0109620:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109623:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109627:	8b 45 08             	mov    0x8(%ebp),%eax
c010962a:	89 04 24             	mov    %eax,(%esp)
c010962d:	e8 05 00 00 00       	call   c0109637 <vprintfmt>
    va_end(ap);
}
c0109632:	90                   	nop
c0109633:	89 ec                	mov    %ebp,%esp
c0109635:	5d                   	pop    %ebp
c0109636:	c3                   	ret    

c0109637 <vprintfmt>:
 *
 * Call this function if you are already dealing with a va_list.
 * Or you probably want printfmt() instead.
 * */
void
vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) {
c0109637:	55                   	push   %ebp
c0109638:	89 e5                	mov    %esp,%ebp
c010963a:	56                   	push   %esi
c010963b:	53                   	push   %ebx
c010963c:	83 ec 40             	sub    $0x40,%esp
    register int ch, err;
    unsigned long long num;
    int base, width, precision, lflag, altflag;

    while (1) {
        while ((ch = *(unsigned char *)fmt ++) != '%') {
c010963f:	eb 17                	jmp    c0109658 <vprintfmt+0x21>
            if (ch == '\0') {
c0109641:	85 db                	test   %ebx,%ebx
c0109643:	0f 84 bf 03 00 00    	je     c0109a08 <vprintfmt+0x3d1>
                return;
            }
            putch(ch, putdat);
c0109649:	8b 45 0c             	mov    0xc(%ebp),%eax
c010964c:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109650:	89 1c 24             	mov    %ebx,(%esp)
c0109653:	8b 45 08             	mov    0x8(%ebp),%eax
c0109656:	ff d0                	call   *%eax
        while ((ch = *(unsigned char *)fmt ++) != '%') {
c0109658:	8b 45 10             	mov    0x10(%ebp),%eax
c010965b:	8d 50 01             	lea    0x1(%eax),%edx
c010965e:	89 55 10             	mov    %edx,0x10(%ebp)
c0109661:	0f b6 00             	movzbl (%eax),%eax
c0109664:	0f b6 d8             	movzbl %al,%ebx
c0109667:	83 fb 25             	cmp    $0x25,%ebx
c010966a:	75 d5                	jne    c0109641 <vprintfmt+0xa>
        }

        // Process a %-escape sequence
        char padc = ' ';
c010966c:	c6 45 db 20          	movb   $0x20,-0x25(%ebp)
        width = precision = -1;
c0109670:	c7 45 e4 ff ff ff ff 	movl   $0xffffffff,-0x1c(%ebp)
c0109677:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c010967a:	89 45 e8             	mov    %eax,-0x18(%ebp)
        lflag = altflag = 0;
c010967d:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
c0109684:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0109687:	89 45 e0             	mov    %eax,-0x20(%ebp)

    reswitch:
        switch (ch = *(unsigned char *)fmt ++) {
c010968a:	8b 45 10             	mov    0x10(%ebp),%eax
c010968d:	8d 50 01             	lea    0x1(%eax),%edx
c0109690:	89 55 10             	mov    %edx,0x10(%ebp)
c0109693:	0f b6 00             	movzbl (%eax),%eax
c0109696:	0f b6 d8             	movzbl %al,%ebx
c0109699:	8d 43 dd             	lea    -0x23(%ebx),%eax
c010969c:	83 f8 55             	cmp    $0x55,%eax
c010969f:	0f 87 37 03 00 00    	ja     c01099dc <vprintfmt+0x3a5>
c01096a5:	8b 04 85 60 c2 10 c0 	mov    -0x3fef3da0(,%eax,4),%eax
c01096ac:	ff e0                	jmp    *%eax

        // flag to pad on the right
        case '-':
            padc = '-';
c01096ae:	c6 45 db 2d          	movb   $0x2d,-0x25(%ebp)
            goto reswitch;
c01096b2:	eb d6                	jmp    c010968a <vprintfmt+0x53>

        // flag to pad with 0's instead of spaces
        case '0':
            padc = '0';
c01096b4:	c6 45 db 30          	movb   $0x30,-0x25(%ebp)
            goto reswitch;
c01096b8:	eb d0                	jmp    c010968a <vprintfmt+0x53>

        // width field
        case '1' ... '9':
            for (precision = 0; ; ++ fmt) {
c01096ba:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
                precision = precision * 10 + ch - '0';
c01096c1:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c01096c4:	89 d0                	mov    %edx,%eax
c01096c6:	c1 e0 02             	shl    $0x2,%eax
c01096c9:	01 d0                	add    %edx,%eax
c01096cb:	01 c0                	add    %eax,%eax
c01096cd:	01 d8                	add    %ebx,%eax
c01096cf:	83 e8 30             	sub    $0x30,%eax
c01096d2:	89 45 e4             	mov    %eax,-0x1c(%ebp)
                ch = *fmt;
c01096d5:	8b 45 10             	mov    0x10(%ebp),%eax
c01096d8:	0f b6 00             	movzbl (%eax),%eax
c01096db:	0f be d8             	movsbl %al,%ebx
                if (ch < '0' || ch > '9') {
c01096de:	83 fb 2f             	cmp    $0x2f,%ebx
c01096e1:	7e 38                	jle    c010971b <vprintfmt+0xe4>
c01096e3:	83 fb 39             	cmp    $0x39,%ebx
c01096e6:	7f 33                	jg     c010971b <vprintfmt+0xe4>
            for (precision = 0; ; ++ fmt) {
c01096e8:	ff 45 10             	incl   0x10(%ebp)
                precision = precision * 10 + ch - '0';
c01096eb:	eb d4                	jmp    c01096c1 <vprintfmt+0x8a>
                }
            }
            goto process_precision;

        case '*':
            precision = va_arg(ap, int);
c01096ed:	8b 45 14             	mov    0x14(%ebp),%eax
c01096f0:	8d 50 04             	lea    0x4(%eax),%edx
c01096f3:	89 55 14             	mov    %edx,0x14(%ebp)
c01096f6:	8b 00                	mov    (%eax),%eax
c01096f8:	89 45 e4             	mov    %eax,-0x1c(%ebp)
            goto process_precision;
c01096fb:	eb 1f                	jmp    c010971c <vprintfmt+0xe5>

        case '.':
            if (width < 0)
c01096fd:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0109701:	79 87                	jns    c010968a <vprintfmt+0x53>
                width = 0;
c0109703:	c7 45 e8 00 00 00 00 	movl   $0x0,-0x18(%ebp)
            goto reswitch;
c010970a:	e9 7b ff ff ff       	jmp    c010968a <vprintfmt+0x53>

        case '#':
            altflag = 1;
c010970f:	c7 45 dc 01 00 00 00 	movl   $0x1,-0x24(%ebp)
            goto reswitch;
c0109716:	e9 6f ff ff ff       	jmp    c010968a <vprintfmt+0x53>
            goto process_precision;
c010971b:	90                   	nop

        process_precision:
            if (width < 0)
c010971c:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0109720:	0f 89 64 ff ff ff    	jns    c010968a <vprintfmt+0x53>
                width = precision, precision = -1;
c0109726:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c0109729:	89 45 e8             	mov    %eax,-0x18(%ebp)
c010972c:	c7 45 e4 ff ff ff ff 	movl   $0xffffffff,-0x1c(%ebp)
            goto reswitch;
c0109733:	e9 52 ff ff ff       	jmp    c010968a <vprintfmt+0x53>

        // long flag (doubled for long long)
        case 'l':
            lflag ++;
c0109738:	ff 45 e0             	incl   -0x20(%ebp)
            goto reswitch;
c010973b:	e9 4a ff ff ff       	jmp    c010968a <vprintfmt+0x53>

        // character
        case 'c':
            putch(va_arg(ap, int), putdat);
c0109740:	8b 45 14             	mov    0x14(%ebp),%eax
c0109743:	8d 50 04             	lea    0x4(%eax),%edx
c0109746:	89 55 14             	mov    %edx,0x14(%ebp)
c0109749:	8b 00                	mov    (%eax),%eax
c010974b:	8b 55 0c             	mov    0xc(%ebp),%edx
c010974e:	89 54 24 04          	mov    %edx,0x4(%esp)
c0109752:	89 04 24             	mov    %eax,(%esp)
c0109755:	8b 45 08             	mov    0x8(%ebp),%eax
c0109758:	ff d0                	call   *%eax
            break;
c010975a:	e9 a4 02 00 00       	jmp    c0109a03 <vprintfmt+0x3cc>

        // error message
        case 'e':
            err = va_arg(ap, int);
c010975f:	8b 45 14             	mov    0x14(%ebp),%eax
c0109762:	8d 50 04             	lea    0x4(%eax),%edx
c0109765:	89 55 14             	mov    %edx,0x14(%ebp)
c0109768:	8b 18                	mov    (%eax),%ebx
            if (err < 0) {
c010976a:	85 db                	test   %ebx,%ebx
c010976c:	79 02                	jns    c0109770 <vprintfmt+0x139>
                err = -err;
c010976e:	f7 db                	neg    %ebx
            }
            if (err > MAXERROR || (p = error_string[err]) == NULL) {
c0109770:	83 fb 06             	cmp    $0x6,%ebx
c0109773:	7f 0b                	jg     c0109780 <vprintfmt+0x149>
c0109775:	8b 34 9d 20 c2 10 c0 	mov    -0x3fef3de0(,%ebx,4),%esi
c010977c:	85 f6                	test   %esi,%esi
c010977e:	75 23                	jne    c01097a3 <vprintfmt+0x16c>
                printfmt(putch, putdat, "error %d", err);
c0109780:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
c0109784:	c7 44 24 08 4d c2 10 	movl   $0xc010c24d,0x8(%esp)
c010978b:	c0 
c010978c:	8b 45 0c             	mov    0xc(%ebp),%eax
c010978f:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109793:	8b 45 08             	mov    0x8(%ebp),%eax
c0109796:	89 04 24             	mov    %eax,(%esp)
c0109799:	e8 68 fe ff ff       	call   c0109606 <printfmt>
            }
            else {
                printfmt(putch, putdat, "%s", p);
            }
            break;
c010979e:	e9 60 02 00 00       	jmp    c0109a03 <vprintfmt+0x3cc>
                printfmt(putch, putdat, "%s", p);
c01097a3:	89 74 24 0c          	mov    %esi,0xc(%esp)
c01097a7:	c7 44 24 08 56 c2 10 	movl   $0xc010c256,0x8(%esp)
c01097ae:	c0 
c01097af:	8b 45 0c             	mov    0xc(%ebp),%eax
c01097b2:	89 44 24 04          	mov    %eax,0x4(%esp)
c01097b6:	8b 45 08             	mov    0x8(%ebp),%eax
c01097b9:	89 04 24             	mov    %eax,(%esp)
c01097bc:	e8 45 fe ff ff       	call   c0109606 <printfmt>
            break;
c01097c1:	e9 3d 02 00 00       	jmp    c0109a03 <vprintfmt+0x3cc>

        // string
        case 's':
            if ((p = va_arg(ap, char *)) == NULL) {
c01097c6:	8b 45 14             	mov    0x14(%ebp),%eax
c01097c9:	8d 50 04             	lea    0x4(%eax),%edx
c01097cc:	89 55 14             	mov    %edx,0x14(%ebp)
c01097cf:	8b 30                	mov    (%eax),%esi
c01097d1:	85 f6                	test   %esi,%esi
c01097d3:	75 05                	jne    c01097da <vprintfmt+0x1a3>
                p = "(null)";
c01097d5:	be 59 c2 10 c0       	mov    $0xc010c259,%esi
            }
            if (width > 0 && padc != '-') {
c01097da:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c01097de:	7e 76                	jle    c0109856 <vprintfmt+0x21f>
c01097e0:	80 7d db 2d          	cmpb   $0x2d,-0x25(%ebp)
c01097e4:	74 70                	je     c0109856 <vprintfmt+0x21f>
                for (width -= strnlen(p, precision); width > 0; width --) {
c01097e6:	8b 45 e4             	mov    -0x1c(%ebp),%eax
c01097e9:	89 44 24 04          	mov    %eax,0x4(%esp)
c01097ed:	89 34 24             	mov    %esi,(%esp)
c01097f0:	e8 ee 03 00 00       	call   c0109be3 <strnlen>
c01097f5:	89 c2                	mov    %eax,%edx
c01097f7:	8b 45 e8             	mov    -0x18(%ebp),%eax
c01097fa:	29 d0                	sub    %edx,%eax
c01097fc:	89 45 e8             	mov    %eax,-0x18(%ebp)
c01097ff:	eb 16                	jmp    c0109817 <vprintfmt+0x1e0>
                    putch(padc, putdat);
c0109801:	0f be 45 db          	movsbl -0x25(%ebp),%eax
c0109805:	8b 55 0c             	mov    0xc(%ebp),%edx
c0109808:	89 54 24 04          	mov    %edx,0x4(%esp)
c010980c:	89 04 24             	mov    %eax,(%esp)
c010980f:	8b 45 08             	mov    0x8(%ebp),%eax
c0109812:	ff d0                	call   *%eax
                for (width -= strnlen(p, precision); width > 0; width --) {
c0109814:	ff 4d e8             	decl   -0x18(%ebp)
c0109817:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c010981b:	7f e4                	jg     c0109801 <vprintfmt+0x1ca>
                }
            }
            for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) {
c010981d:	eb 37                	jmp    c0109856 <vprintfmt+0x21f>
                if (altflag && (ch < ' ' || ch > '~')) {
c010981f:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
c0109823:	74 1f                	je     c0109844 <vprintfmt+0x20d>
c0109825:	83 fb 1f             	cmp    $0x1f,%ebx
c0109828:	7e 05                	jle    c010982f <vprintfmt+0x1f8>
c010982a:	83 fb 7e             	cmp    $0x7e,%ebx
c010982d:	7e 15                	jle    c0109844 <vprintfmt+0x20d>
                    putch('?', putdat);
c010982f:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109832:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109836:	c7 04 24 3f 00 00 00 	movl   $0x3f,(%esp)
c010983d:	8b 45 08             	mov    0x8(%ebp),%eax
c0109840:	ff d0                	call   *%eax
c0109842:	eb 0f                	jmp    c0109853 <vprintfmt+0x21c>
                }
                else {
                    putch(ch, putdat);
c0109844:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109847:	89 44 24 04          	mov    %eax,0x4(%esp)
c010984b:	89 1c 24             	mov    %ebx,(%esp)
c010984e:	8b 45 08             	mov    0x8(%ebp),%eax
c0109851:	ff d0                	call   *%eax
            for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) {
c0109853:	ff 4d e8             	decl   -0x18(%ebp)
c0109856:	89 f0                	mov    %esi,%eax
c0109858:	8d 70 01             	lea    0x1(%eax),%esi
c010985b:	0f b6 00             	movzbl (%eax),%eax
c010985e:	0f be d8             	movsbl %al,%ebx
c0109861:	85 db                	test   %ebx,%ebx
c0109863:	74 27                	je     c010988c <vprintfmt+0x255>
c0109865:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0109869:	78 b4                	js     c010981f <vprintfmt+0x1e8>
c010986b:	ff 4d e4             	decl   -0x1c(%ebp)
c010986e:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
c0109872:	79 ab                	jns    c010981f <vprintfmt+0x1e8>
                }
            }
            for (; width > 0; width --) {
c0109874:	eb 16                	jmp    c010988c <vprintfmt+0x255>
                putch(' ', putdat);
c0109876:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109879:	89 44 24 04          	mov    %eax,0x4(%esp)
c010987d:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
c0109884:	8b 45 08             	mov    0x8(%ebp),%eax
c0109887:	ff d0                	call   *%eax
            for (; width > 0; width --) {
c0109889:	ff 4d e8             	decl   -0x18(%ebp)
c010988c:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0109890:	7f e4                	jg     c0109876 <vprintfmt+0x23f>
            }
            break;
c0109892:	e9 6c 01 00 00       	jmp    c0109a03 <vprintfmt+0x3cc>

        // (signed) decimal
        case 'd':
            num = getint(&ap, lflag);
c0109897:	8b 45 e0             	mov    -0x20(%ebp),%eax
c010989a:	89 44 24 04          	mov    %eax,0x4(%esp)
c010989e:	8d 45 14             	lea    0x14(%ebp),%eax
c01098a1:	89 04 24             	mov    %eax,(%esp)
c01098a4:	e8 16 fd ff ff       	call   c01095bf <getint>
c01098a9:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01098ac:	89 55 f4             	mov    %edx,-0xc(%ebp)
            if ((long long)num < 0) {
c01098af:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01098b2:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01098b5:	85 d2                	test   %edx,%edx
c01098b7:	79 26                	jns    c01098df <vprintfmt+0x2a8>
                putch('-', putdat);
c01098b9:	8b 45 0c             	mov    0xc(%ebp),%eax
c01098bc:	89 44 24 04          	mov    %eax,0x4(%esp)
c01098c0:	c7 04 24 2d 00 00 00 	movl   $0x2d,(%esp)
c01098c7:	8b 45 08             	mov    0x8(%ebp),%eax
c01098ca:	ff d0                	call   *%eax
                num = -(long long)num;
c01098cc:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01098cf:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01098d2:	f7 d8                	neg    %eax
c01098d4:	83 d2 00             	adc    $0x0,%edx
c01098d7:	f7 da                	neg    %edx
c01098d9:	89 45 f0             	mov    %eax,-0x10(%ebp)
c01098dc:	89 55 f4             	mov    %edx,-0xc(%ebp)
            }
            base = 10;
c01098df:	c7 45 ec 0a 00 00 00 	movl   $0xa,-0x14(%ebp)
            goto number;
c01098e6:	e9 a8 00 00 00       	jmp    c0109993 <vprintfmt+0x35c>

        // unsigned decimal
        case 'u':
            num = getuint(&ap, lflag);
c01098eb:	8b 45 e0             	mov    -0x20(%ebp),%eax
c01098ee:	89 44 24 04          	mov    %eax,0x4(%esp)
c01098f2:	8d 45 14             	lea    0x14(%ebp),%eax
c01098f5:	89 04 24             	mov    %eax,(%esp)
c01098f8:	e8 73 fc ff ff       	call   c0109570 <getuint>
c01098fd:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0109900:	89 55 f4             	mov    %edx,-0xc(%ebp)
            base = 10;
c0109903:	c7 45 ec 0a 00 00 00 	movl   $0xa,-0x14(%ebp)
            goto number;
c010990a:	e9 84 00 00 00       	jmp    c0109993 <vprintfmt+0x35c>

        // (unsigned) octal
        case 'o':
            num = getuint(&ap, lflag);
c010990f:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0109912:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109916:	8d 45 14             	lea    0x14(%ebp),%eax
c0109919:	89 04 24             	mov    %eax,(%esp)
c010991c:	e8 4f fc ff ff       	call   c0109570 <getuint>
c0109921:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0109924:	89 55 f4             	mov    %edx,-0xc(%ebp)
            base = 8;
c0109927:	c7 45 ec 08 00 00 00 	movl   $0x8,-0x14(%ebp)
            goto number;
c010992e:	eb 63                	jmp    c0109993 <vprintfmt+0x35c>

        // pointer
        case 'p':
            putch('0', putdat);
c0109930:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109933:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109937:	c7 04 24 30 00 00 00 	movl   $0x30,(%esp)
c010993e:	8b 45 08             	mov    0x8(%ebp),%eax
c0109941:	ff d0                	call   *%eax
            putch('x', putdat);
c0109943:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109946:	89 44 24 04          	mov    %eax,0x4(%esp)
c010994a:	c7 04 24 78 00 00 00 	movl   $0x78,(%esp)
c0109951:	8b 45 08             	mov    0x8(%ebp),%eax
c0109954:	ff d0                	call   *%eax
            num = (unsigned long long)(uintptr_t)va_arg(ap, void *);
c0109956:	8b 45 14             	mov    0x14(%ebp),%eax
c0109959:	8d 50 04             	lea    0x4(%eax),%edx
c010995c:	89 55 14             	mov    %edx,0x14(%ebp)
c010995f:	8b 00                	mov    (%eax),%eax
c0109961:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0109964:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
            base = 16;
c010996b:	c7 45 ec 10 00 00 00 	movl   $0x10,-0x14(%ebp)
            goto number;
c0109972:	eb 1f                	jmp    c0109993 <vprintfmt+0x35c>

        // (unsigned) hexadecimal
        case 'x':
            num = getuint(&ap, lflag);
c0109974:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0109977:	89 44 24 04          	mov    %eax,0x4(%esp)
c010997b:	8d 45 14             	lea    0x14(%ebp),%eax
c010997e:	89 04 24             	mov    %eax,(%esp)
c0109981:	e8 ea fb ff ff       	call   c0109570 <getuint>
c0109986:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0109989:	89 55 f4             	mov    %edx,-0xc(%ebp)
            base = 16;
c010998c:	c7 45 ec 10 00 00 00 	movl   $0x10,-0x14(%ebp)
        number:
            printnum(putch, putdat, num, base, width, padc);
c0109993:	0f be 55 db          	movsbl -0x25(%ebp),%edx
c0109997:	8b 45 ec             	mov    -0x14(%ebp),%eax
c010999a:	89 54 24 18          	mov    %edx,0x18(%esp)
c010999e:	8b 55 e8             	mov    -0x18(%ebp),%edx
c01099a1:	89 54 24 14          	mov    %edx,0x14(%esp)
c01099a5:	89 44 24 10          	mov    %eax,0x10(%esp)
c01099a9:	8b 45 f0             	mov    -0x10(%ebp),%eax
c01099ac:	8b 55 f4             	mov    -0xc(%ebp),%edx
c01099af:	89 44 24 08          	mov    %eax,0x8(%esp)
c01099b3:	89 54 24 0c          	mov    %edx,0xc(%esp)
c01099b7:	8b 45 0c             	mov    0xc(%ebp),%eax
c01099ba:	89 44 24 04          	mov    %eax,0x4(%esp)
c01099be:	8b 45 08             	mov    0x8(%ebp),%eax
c01099c1:	89 04 24             	mov    %eax,(%esp)
c01099c4:	e8 a5 fa ff ff       	call   c010946e <printnum>
            break;
c01099c9:	eb 38                	jmp    c0109a03 <vprintfmt+0x3cc>

        // escaped '%' character
        case '%':
            putch(ch, putdat);
c01099cb:	8b 45 0c             	mov    0xc(%ebp),%eax
c01099ce:	89 44 24 04          	mov    %eax,0x4(%esp)
c01099d2:	89 1c 24             	mov    %ebx,(%esp)
c01099d5:	8b 45 08             	mov    0x8(%ebp),%eax
c01099d8:	ff d0                	call   *%eax
            break;
c01099da:	eb 27                	jmp    c0109a03 <vprintfmt+0x3cc>

        // unrecognized escape sequence - just print it literally
        default:
            putch('%', putdat);
c01099dc:	8b 45 0c             	mov    0xc(%ebp),%eax
c01099df:	89 44 24 04          	mov    %eax,0x4(%esp)
c01099e3:	c7 04 24 25 00 00 00 	movl   $0x25,(%esp)
c01099ea:	8b 45 08             	mov    0x8(%ebp),%eax
c01099ed:	ff d0                	call   *%eax
            for (fmt --; fmt[-1] != '%'; fmt --)
c01099ef:	ff 4d 10             	decl   0x10(%ebp)
c01099f2:	eb 03                	jmp    c01099f7 <vprintfmt+0x3c0>
c01099f4:	ff 4d 10             	decl   0x10(%ebp)
c01099f7:	8b 45 10             	mov    0x10(%ebp),%eax
c01099fa:	48                   	dec    %eax
c01099fb:	0f b6 00             	movzbl (%eax),%eax
c01099fe:	3c 25                	cmp    $0x25,%al
c0109a00:	75 f2                	jne    c01099f4 <vprintfmt+0x3bd>
                /* do nothing */;
            break;
c0109a02:	90                   	nop
    while (1) {
c0109a03:	e9 37 fc ff ff       	jmp    c010963f <vprintfmt+0x8>
                return;
c0109a08:	90                   	nop
        }
    }
}
c0109a09:	83 c4 40             	add    $0x40,%esp
c0109a0c:	5b                   	pop    %ebx
c0109a0d:	5e                   	pop    %esi
c0109a0e:	5d                   	pop    %ebp
c0109a0f:	c3                   	ret    

c0109a10 <sprintputch>:
 * sprintputch - 'print' a single character in a buffer
 * @ch:         the character will be printed
 * @b:          the buffer to place the character @ch
 * */
static void
sprintputch(int ch, struct sprintbuf *b) {
c0109a10:	55                   	push   %ebp
c0109a11:	89 e5                	mov    %esp,%ebp
    b->cnt ++;
c0109a13:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109a16:	8b 40 08             	mov    0x8(%eax),%eax
c0109a19:	8d 50 01             	lea    0x1(%eax),%edx
c0109a1c:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109a1f:	89 50 08             	mov    %edx,0x8(%eax)
    if (b->buf < b->ebuf) {
c0109a22:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109a25:	8b 10                	mov    (%eax),%edx
c0109a27:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109a2a:	8b 40 04             	mov    0x4(%eax),%eax
c0109a2d:	39 c2                	cmp    %eax,%edx
c0109a2f:	73 12                	jae    c0109a43 <sprintputch+0x33>
        *b->buf ++ = ch;
c0109a31:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109a34:	8b 00                	mov    (%eax),%eax
c0109a36:	8d 48 01             	lea    0x1(%eax),%ecx
c0109a39:	8b 55 0c             	mov    0xc(%ebp),%edx
c0109a3c:	89 0a                	mov    %ecx,(%edx)
c0109a3e:	8b 55 08             	mov    0x8(%ebp),%edx
c0109a41:	88 10                	mov    %dl,(%eax)
    }
}
c0109a43:	90                   	nop
c0109a44:	5d                   	pop    %ebp
c0109a45:	c3                   	ret    

c0109a46 <snprintf>:
 * @str:        the buffer to place the result into
 * @size:       the size of buffer, including the trailing null space
 * @fmt:        the format string to use
 * */
int
snprintf(char *str, size_t size, const char *fmt, ...) {
c0109a46:	55                   	push   %ebp
c0109a47:	89 e5                	mov    %esp,%ebp
c0109a49:	83 ec 28             	sub    $0x28,%esp
    va_list ap;
    int cnt;
    va_start(ap, fmt);
c0109a4c:	8d 45 14             	lea    0x14(%ebp),%eax
c0109a4f:	89 45 f0             	mov    %eax,-0x10(%ebp)
    cnt = vsnprintf(str, size, fmt, ap);
c0109a52:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109a55:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0109a59:	8b 45 10             	mov    0x10(%ebp),%eax
c0109a5c:	89 44 24 08          	mov    %eax,0x8(%esp)
c0109a60:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109a63:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109a67:	8b 45 08             	mov    0x8(%ebp),%eax
c0109a6a:	89 04 24             	mov    %eax,(%esp)
c0109a6d:	e8 0a 00 00 00       	call   c0109a7c <vsnprintf>
c0109a72:	89 45 f4             	mov    %eax,-0xc(%ebp)
    va_end(ap);
    return cnt;
c0109a75:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0109a78:	89 ec                	mov    %ebp,%esp
c0109a7a:	5d                   	pop    %ebp
c0109a7b:	c3                   	ret    

c0109a7c <vsnprintf>:
 *
 * Call this function if you are already dealing with a va_list.
 * Or you probably want snprintf() instead.
 * */
int
vsnprintf(char *str, size_t size, const char *fmt, va_list ap) {
c0109a7c:	55                   	push   %ebp
c0109a7d:	89 e5                	mov    %esp,%ebp
c0109a7f:	83 ec 28             	sub    $0x28,%esp
    struct sprintbuf b = {str, str + size - 1, 0};
c0109a82:	8b 45 08             	mov    0x8(%ebp),%eax
c0109a85:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0109a88:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109a8b:	8d 50 ff             	lea    -0x1(%eax),%edx
c0109a8e:	8b 45 08             	mov    0x8(%ebp),%eax
c0109a91:	01 d0                	add    %edx,%eax
c0109a93:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0109a96:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
    if (str == NULL || b.buf > b.ebuf) {
c0109a9d:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
c0109aa1:	74 0a                	je     c0109aad <vsnprintf+0x31>
c0109aa3:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0109aa6:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109aa9:	39 c2                	cmp    %eax,%edx
c0109aab:	76 07                	jbe    c0109ab4 <vsnprintf+0x38>
        return -E_INVAL;
c0109aad:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
c0109ab2:	eb 2a                	jmp    c0109ade <vsnprintf+0x62>
    }
    // print the string to the buffer
    vprintfmt((void*)sprintputch, &b, fmt, ap);
c0109ab4:	8b 45 14             	mov    0x14(%ebp),%eax
c0109ab7:	89 44 24 0c          	mov    %eax,0xc(%esp)
c0109abb:	8b 45 10             	mov    0x10(%ebp),%eax
c0109abe:	89 44 24 08          	mov    %eax,0x8(%esp)
c0109ac2:	8d 45 ec             	lea    -0x14(%ebp),%eax
c0109ac5:	89 44 24 04          	mov    %eax,0x4(%esp)
c0109ac9:	c7 04 24 10 9a 10 c0 	movl   $0xc0109a10,(%esp)
c0109ad0:	e8 62 fb ff ff       	call   c0109637 <vprintfmt>
    // null terminate the buffer
    *b.buf = '\0';
c0109ad5:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109ad8:	c6 00 00             	movb   $0x0,(%eax)
    return b.cnt;
c0109adb:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
c0109ade:	89 ec                	mov    %ebp,%esp
c0109ae0:	5d                   	pop    %ebp
c0109ae1:	c3                   	ret    

c0109ae2 <rand>:
 * rand - returns a pseudo-random integer
 *
 * The rand() function return a value in the range [0, RAND_MAX].
 * */
int
rand(void) {
c0109ae2:	55                   	push   %ebp
c0109ae3:	89 e5                	mov    %esp,%ebp
c0109ae5:	57                   	push   %edi
c0109ae6:	56                   	push   %esi
c0109ae7:	53                   	push   %ebx
c0109ae8:	83 ec 24             	sub    $0x24,%esp
    next = (next * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1);
c0109aeb:	a1 88 8a 12 c0       	mov    0xc0128a88,%eax
c0109af0:	8b 15 8c 8a 12 c0    	mov    0xc0128a8c,%edx
c0109af6:	69 fa 6d e6 ec de    	imul   $0xdeece66d,%edx,%edi
c0109afc:	6b f0 05             	imul   $0x5,%eax,%esi
c0109aff:	01 fe                	add    %edi,%esi
c0109b01:	bf 6d e6 ec de       	mov    $0xdeece66d,%edi
c0109b06:	f7 e7                	mul    %edi
c0109b08:	01 d6                	add    %edx,%esi
c0109b0a:	89 f2                	mov    %esi,%edx
c0109b0c:	83 c0 0b             	add    $0xb,%eax
c0109b0f:	83 d2 00             	adc    $0x0,%edx
c0109b12:	89 c7                	mov    %eax,%edi
c0109b14:	83 e7 ff             	and    $0xffffffff,%edi
c0109b17:	89 f9                	mov    %edi,%ecx
c0109b19:	0f b7 da             	movzwl %dx,%ebx
c0109b1c:	89 0d 88 8a 12 c0    	mov    %ecx,0xc0128a88
c0109b22:	89 1d 8c 8a 12 c0    	mov    %ebx,0xc0128a8c
    unsigned long long result = (next >> 12);
c0109b28:	a1 88 8a 12 c0       	mov    0xc0128a88,%eax
c0109b2d:	8b 15 8c 8a 12 c0    	mov    0xc0128a8c,%edx
c0109b33:	0f ac d0 0c          	shrd   $0xc,%edx,%eax
c0109b37:	c1 ea 0c             	shr    $0xc,%edx
c0109b3a:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0109b3d:	89 55 e4             	mov    %edx,-0x1c(%ebp)
    return (int)do_div(result, RAND_MAX + 1);
c0109b40:	c7 45 dc 00 00 00 80 	movl   $0x80000000,-0x24(%ebp)
c0109b47:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0109b4a:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0109b4d:	89 45 d8             	mov    %eax,-0x28(%ebp)
c0109b50:	89 55 e8             	mov    %edx,-0x18(%ebp)
c0109b53:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109b56:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0109b59:	83 7d e8 00          	cmpl   $0x0,-0x18(%ebp)
c0109b5d:	74 1c                	je     c0109b7b <rand+0x99>
c0109b5f:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109b62:	ba 00 00 00 00       	mov    $0x0,%edx
c0109b67:	f7 75 dc             	divl   -0x24(%ebp)
c0109b6a:	89 55 ec             	mov    %edx,-0x14(%ebp)
c0109b6d:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109b70:	ba 00 00 00 00       	mov    $0x0,%edx
c0109b75:	f7 75 dc             	divl   -0x24(%ebp)
c0109b78:	89 45 e8             	mov    %eax,-0x18(%ebp)
c0109b7b:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0109b7e:	8b 55 ec             	mov    -0x14(%ebp),%edx
c0109b81:	f7 75 dc             	divl   -0x24(%ebp)
c0109b84:	89 45 d8             	mov    %eax,-0x28(%ebp)
c0109b87:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c0109b8a:	8b 45 d8             	mov    -0x28(%ebp),%eax
c0109b8d:	8b 55 e8             	mov    -0x18(%ebp),%edx
c0109b90:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0109b93:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c0109b96:	8b 45 d4             	mov    -0x2c(%ebp),%eax
}
c0109b99:	83 c4 24             	add    $0x24,%esp
c0109b9c:	5b                   	pop    %ebx
c0109b9d:	5e                   	pop    %esi
c0109b9e:	5f                   	pop    %edi
c0109b9f:	5d                   	pop    %ebp
c0109ba0:	c3                   	ret    

c0109ba1 <srand>:
/* *
 * srand - seed the random number generator with the given number
 * @seed:   the required seed number
 * */
void
srand(unsigned int seed) {
c0109ba1:	55                   	push   %ebp
c0109ba2:	89 e5                	mov    %esp,%ebp
    next = seed;
c0109ba4:	8b 45 08             	mov    0x8(%ebp),%eax
c0109ba7:	ba 00 00 00 00       	mov    $0x0,%edx
c0109bac:	a3 88 8a 12 c0       	mov    %eax,0xc0128a88
c0109bb1:	89 15 8c 8a 12 c0    	mov    %edx,0xc0128a8c
}
c0109bb7:	90                   	nop
c0109bb8:	5d                   	pop    %ebp
c0109bb9:	c3                   	ret    

c0109bba <strlen>:
 * @s:      the input string
 *
 * The strlen() function returns the length of string @s.
 * */
size_t
strlen(const char *s) {
c0109bba:	55                   	push   %ebp
c0109bbb:	89 e5                	mov    %esp,%ebp
c0109bbd:	83 ec 10             	sub    $0x10,%esp
    size_t cnt = 0;
c0109bc0:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    while (*s ++ != '\0') {
c0109bc7:	eb 03                	jmp    c0109bcc <strlen+0x12>
        cnt ++;
c0109bc9:	ff 45 fc             	incl   -0x4(%ebp)
    while (*s ++ != '\0') {
c0109bcc:	8b 45 08             	mov    0x8(%ebp),%eax
c0109bcf:	8d 50 01             	lea    0x1(%eax),%edx
c0109bd2:	89 55 08             	mov    %edx,0x8(%ebp)
c0109bd5:	0f b6 00             	movzbl (%eax),%eax
c0109bd8:	84 c0                	test   %al,%al
c0109bda:	75 ed                	jne    c0109bc9 <strlen+0xf>
    }
    return cnt;
c0109bdc:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c0109bdf:	89 ec                	mov    %ebp,%esp
c0109be1:	5d                   	pop    %ebp
c0109be2:	c3                   	ret    

c0109be3 <strnlen>:
 * The return value is strlen(s), if that is less than @len, or
 * @len if there is no '\0' character among the first @len characters
 * pointed by @s.
 * */
size_t
strnlen(const char *s, size_t len) {
c0109be3:	55                   	push   %ebp
c0109be4:	89 e5                	mov    %esp,%ebp
c0109be6:	83 ec 10             	sub    $0x10,%esp
    size_t cnt = 0;
c0109be9:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    while (cnt < len && *s ++ != '\0') {
c0109bf0:	eb 03                	jmp    c0109bf5 <strnlen+0x12>
        cnt ++;
c0109bf2:	ff 45 fc             	incl   -0x4(%ebp)
    while (cnt < len && *s ++ != '\0') {
c0109bf5:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0109bf8:	3b 45 0c             	cmp    0xc(%ebp),%eax
c0109bfb:	73 10                	jae    c0109c0d <strnlen+0x2a>
c0109bfd:	8b 45 08             	mov    0x8(%ebp),%eax
c0109c00:	8d 50 01             	lea    0x1(%eax),%edx
c0109c03:	89 55 08             	mov    %edx,0x8(%ebp)
c0109c06:	0f b6 00             	movzbl (%eax),%eax
c0109c09:	84 c0                	test   %al,%al
c0109c0b:	75 e5                	jne    c0109bf2 <strnlen+0xf>
    }
    return cnt;
c0109c0d:	8b 45 fc             	mov    -0x4(%ebp),%eax
}
c0109c10:	89 ec                	mov    %ebp,%esp
c0109c12:	5d                   	pop    %ebp
c0109c13:	c3                   	ret    

c0109c14 <strcpy>:
 * To avoid overflows, the size of array pointed by @dst should be long enough to
 * contain the same string as @src (including the terminating null character), and
 * should not overlap in memory with @src.
 * */
char *
strcpy(char *dst, const char *src) {
c0109c14:	55                   	push   %ebp
c0109c15:	89 e5                	mov    %esp,%ebp
c0109c17:	57                   	push   %edi
c0109c18:	56                   	push   %esi
c0109c19:	83 ec 20             	sub    $0x20,%esp
c0109c1c:	8b 45 08             	mov    0x8(%ebp),%eax
c0109c1f:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109c22:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109c25:	89 45 f0             	mov    %eax,-0x10(%ebp)
#ifndef __HAVE_ARCH_STRCPY
#define __HAVE_ARCH_STRCPY
static inline char *
__strcpy(char *dst, const char *src) {
    int d0, d1, d2;
    asm volatile (
c0109c28:	8b 55 f0             	mov    -0x10(%ebp),%edx
c0109c2b:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109c2e:	89 d1                	mov    %edx,%ecx
c0109c30:	89 c2                	mov    %eax,%edx
c0109c32:	89 ce                	mov    %ecx,%esi
c0109c34:	89 d7                	mov    %edx,%edi
c0109c36:	ac                   	lods   %ds:(%esi),%al
c0109c37:	aa                   	stos   %al,%es:(%edi)
c0109c38:	84 c0                	test   %al,%al
c0109c3a:	75 fa                	jne    c0109c36 <strcpy+0x22>
c0109c3c:	89 fa                	mov    %edi,%edx
c0109c3e:	89 f1                	mov    %esi,%ecx
c0109c40:	89 4d ec             	mov    %ecx,-0x14(%ebp)
c0109c43:	89 55 e8             	mov    %edx,-0x18(%ebp)
c0109c46:	89 45 e4             	mov    %eax,-0x1c(%ebp)
        "stosb;"
        "testb %%al, %%al;"
        "jne 1b;"
        : "=&S" (d0), "=&D" (d1), "=&a" (d2)
        : "0" (src), "1" (dst) : "memory");
    return dst;
c0109c49:	8b 45 f4             	mov    -0xc(%ebp),%eax
    char *p = dst;
    while ((*p ++ = *src ++) != '\0')
        /* nothing */;
    return dst;
#endif /* __HAVE_ARCH_STRCPY */
}
c0109c4c:	83 c4 20             	add    $0x20,%esp
c0109c4f:	5e                   	pop    %esi
c0109c50:	5f                   	pop    %edi
c0109c51:	5d                   	pop    %ebp
c0109c52:	c3                   	ret    

c0109c53 <strncpy>:
 * @len:    maximum number of characters to be copied from @src
 *
 * The return value is @dst
 * */
char *
strncpy(char *dst, const char *src, size_t len) {
c0109c53:	55                   	push   %ebp
c0109c54:	89 e5                	mov    %esp,%ebp
c0109c56:	83 ec 10             	sub    $0x10,%esp
    char *p = dst;
c0109c59:	8b 45 08             	mov    0x8(%ebp),%eax
c0109c5c:	89 45 fc             	mov    %eax,-0x4(%ebp)
    while (len > 0) {
c0109c5f:	eb 1e                	jmp    c0109c7f <strncpy+0x2c>
        if ((*p = *src) != '\0') {
c0109c61:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109c64:	0f b6 10             	movzbl (%eax),%edx
c0109c67:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0109c6a:	88 10                	mov    %dl,(%eax)
c0109c6c:	8b 45 fc             	mov    -0x4(%ebp),%eax
c0109c6f:	0f b6 00             	movzbl (%eax),%eax
c0109c72:	84 c0                	test   %al,%al
c0109c74:	74 03                	je     c0109c79 <strncpy+0x26>
            src ++;
c0109c76:	ff 45 0c             	incl   0xc(%ebp)
        }
        p ++, len --;
c0109c79:	ff 45 fc             	incl   -0x4(%ebp)
c0109c7c:	ff 4d 10             	decl   0x10(%ebp)
    while (len > 0) {
c0109c7f:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0109c83:	75 dc                	jne    c0109c61 <strncpy+0xe>
    }
    return dst;
c0109c85:	8b 45 08             	mov    0x8(%ebp),%eax
}
c0109c88:	89 ec                	mov    %ebp,%esp
c0109c8a:	5d                   	pop    %ebp
c0109c8b:	c3                   	ret    

c0109c8c <strcmp>:
 * - A value greater than zero indicates that the first character that does
 *   not match has a greater value in @s1 than in @s2;
 * - And a value less than zero indicates the opposite.
 * */
int
strcmp(const char *s1, const char *s2) {
c0109c8c:	55                   	push   %ebp
c0109c8d:	89 e5                	mov    %esp,%ebp
c0109c8f:	57                   	push   %edi
c0109c90:	56                   	push   %esi
c0109c91:	83 ec 20             	sub    $0x20,%esp
c0109c94:	8b 45 08             	mov    0x8(%ebp),%eax
c0109c97:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109c9a:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109c9d:	89 45 f0             	mov    %eax,-0x10(%ebp)
    asm volatile (
c0109ca0:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0109ca3:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109ca6:	89 d1                	mov    %edx,%ecx
c0109ca8:	89 c2                	mov    %eax,%edx
c0109caa:	89 ce                	mov    %ecx,%esi
c0109cac:	89 d7                	mov    %edx,%edi
c0109cae:	ac                   	lods   %ds:(%esi),%al
c0109caf:	ae                   	scas   %es:(%edi),%al
c0109cb0:	75 08                	jne    c0109cba <strcmp+0x2e>
c0109cb2:	84 c0                	test   %al,%al
c0109cb4:	75 f8                	jne    c0109cae <strcmp+0x22>
c0109cb6:	31 c0                	xor    %eax,%eax
c0109cb8:	eb 04                	jmp    c0109cbe <strcmp+0x32>
c0109cba:	19 c0                	sbb    %eax,%eax
c0109cbc:	0c 01                	or     $0x1,%al
c0109cbe:	89 fa                	mov    %edi,%edx
c0109cc0:	89 f1                	mov    %esi,%ecx
c0109cc2:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0109cc5:	89 4d e8             	mov    %ecx,-0x18(%ebp)
c0109cc8:	89 55 e4             	mov    %edx,-0x1c(%ebp)
    return ret;
c0109ccb:	8b 45 ec             	mov    -0x14(%ebp),%eax
    while (*s1 != '\0' && *s1 == *s2) {
        s1 ++, s2 ++;
    }
    return (int)((unsigned char)*s1 - (unsigned char)*s2);
#endif /* __HAVE_ARCH_STRCMP */
}
c0109cce:	83 c4 20             	add    $0x20,%esp
c0109cd1:	5e                   	pop    %esi
c0109cd2:	5f                   	pop    %edi
c0109cd3:	5d                   	pop    %ebp
c0109cd4:	c3                   	ret    

c0109cd5 <strncmp>:
 * they are equal to each other, it continues with the following pairs until
 * the characters differ, until a terminating null-character is reached, or
 * until @n characters match in both strings, whichever happens first.
 * */
int
strncmp(const char *s1, const char *s2, size_t n) {
c0109cd5:	55                   	push   %ebp
c0109cd6:	89 e5                	mov    %esp,%ebp
    while (n > 0 && *s1 != '\0' && *s1 == *s2) {
c0109cd8:	eb 09                	jmp    c0109ce3 <strncmp+0xe>
        n --, s1 ++, s2 ++;
c0109cda:	ff 4d 10             	decl   0x10(%ebp)
c0109cdd:	ff 45 08             	incl   0x8(%ebp)
c0109ce0:	ff 45 0c             	incl   0xc(%ebp)
    while (n > 0 && *s1 != '\0' && *s1 == *s2) {
c0109ce3:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0109ce7:	74 1a                	je     c0109d03 <strncmp+0x2e>
c0109ce9:	8b 45 08             	mov    0x8(%ebp),%eax
c0109cec:	0f b6 00             	movzbl (%eax),%eax
c0109cef:	84 c0                	test   %al,%al
c0109cf1:	74 10                	je     c0109d03 <strncmp+0x2e>
c0109cf3:	8b 45 08             	mov    0x8(%ebp),%eax
c0109cf6:	0f b6 10             	movzbl (%eax),%edx
c0109cf9:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109cfc:	0f b6 00             	movzbl (%eax),%eax
c0109cff:	38 c2                	cmp    %al,%dl
c0109d01:	74 d7                	je     c0109cda <strncmp+0x5>
    }
    return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2);
c0109d03:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0109d07:	74 18                	je     c0109d21 <strncmp+0x4c>
c0109d09:	8b 45 08             	mov    0x8(%ebp),%eax
c0109d0c:	0f b6 00             	movzbl (%eax),%eax
c0109d0f:	0f b6 d0             	movzbl %al,%edx
c0109d12:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109d15:	0f b6 00             	movzbl (%eax),%eax
c0109d18:	0f b6 c8             	movzbl %al,%ecx
c0109d1b:	89 d0                	mov    %edx,%eax
c0109d1d:	29 c8                	sub    %ecx,%eax
c0109d1f:	eb 05                	jmp    c0109d26 <strncmp+0x51>
c0109d21:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0109d26:	5d                   	pop    %ebp
c0109d27:	c3                   	ret    

c0109d28 <strchr>:
 *
 * The strchr() function returns a pointer to the first occurrence of
 * character in @s. If the value is not found, the function returns 'NULL'.
 * */
char *
strchr(const char *s, char c) {
c0109d28:	55                   	push   %ebp
c0109d29:	89 e5                	mov    %esp,%ebp
c0109d2b:	83 ec 04             	sub    $0x4,%esp
c0109d2e:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109d31:	88 45 fc             	mov    %al,-0x4(%ebp)
    while (*s != '\0') {
c0109d34:	eb 13                	jmp    c0109d49 <strchr+0x21>
        if (*s == c) {
c0109d36:	8b 45 08             	mov    0x8(%ebp),%eax
c0109d39:	0f b6 00             	movzbl (%eax),%eax
c0109d3c:	38 45 fc             	cmp    %al,-0x4(%ebp)
c0109d3f:	75 05                	jne    c0109d46 <strchr+0x1e>
            return (char *)s;
c0109d41:	8b 45 08             	mov    0x8(%ebp),%eax
c0109d44:	eb 12                	jmp    c0109d58 <strchr+0x30>
        }
        s ++;
c0109d46:	ff 45 08             	incl   0x8(%ebp)
    while (*s != '\0') {
c0109d49:	8b 45 08             	mov    0x8(%ebp),%eax
c0109d4c:	0f b6 00             	movzbl (%eax),%eax
c0109d4f:	84 c0                	test   %al,%al
c0109d51:	75 e3                	jne    c0109d36 <strchr+0xe>
    }
    return NULL;
c0109d53:	b8 00 00 00 00       	mov    $0x0,%eax
}
c0109d58:	89 ec                	mov    %ebp,%esp
c0109d5a:	5d                   	pop    %ebp
c0109d5b:	c3                   	ret    

c0109d5c <strfind>:
 * The strfind() function is like strchr() except that if @c is
 * not found in @s, then it returns a pointer to the null byte at the
 * end of @s, rather than 'NULL'.
 * */
char *
strfind(const char *s, char c) {
c0109d5c:	55                   	push   %ebp
c0109d5d:	89 e5                	mov    %esp,%ebp
c0109d5f:	83 ec 04             	sub    $0x4,%esp
c0109d62:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109d65:	88 45 fc             	mov    %al,-0x4(%ebp)
    while (*s != '\0') {
c0109d68:	eb 0e                	jmp    c0109d78 <strfind+0x1c>
        if (*s == c) {
c0109d6a:	8b 45 08             	mov    0x8(%ebp),%eax
c0109d6d:	0f b6 00             	movzbl (%eax),%eax
c0109d70:	38 45 fc             	cmp    %al,-0x4(%ebp)
c0109d73:	74 0f                	je     c0109d84 <strfind+0x28>
            break;
        }
        s ++;
c0109d75:	ff 45 08             	incl   0x8(%ebp)
    while (*s != '\0') {
c0109d78:	8b 45 08             	mov    0x8(%ebp),%eax
c0109d7b:	0f b6 00             	movzbl (%eax),%eax
c0109d7e:	84 c0                	test   %al,%al
c0109d80:	75 e8                	jne    c0109d6a <strfind+0xe>
c0109d82:	eb 01                	jmp    c0109d85 <strfind+0x29>
            break;
c0109d84:	90                   	nop
    }
    return (char *)s;
c0109d85:	8b 45 08             	mov    0x8(%ebp),%eax
}
c0109d88:	89 ec                	mov    %ebp,%esp
c0109d8a:	5d                   	pop    %ebp
c0109d8b:	c3                   	ret    

c0109d8c <strtol>:
 * an optional "0x" or "0X" prefix.
 *
 * The strtol() function returns the converted integral number as a long int value.
 * */
long
strtol(const char *s, char **endptr, int base) {
c0109d8c:	55                   	push   %ebp
c0109d8d:	89 e5                	mov    %esp,%ebp
c0109d8f:	83 ec 10             	sub    $0x10,%esp
    int neg = 0;
c0109d92:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%ebp)
    long val = 0;
c0109d99:	c7 45 f8 00 00 00 00 	movl   $0x0,-0x8(%ebp)

    // gobble initial whitespace
    while (*s == ' ' || *s == '\t') {
c0109da0:	eb 03                	jmp    c0109da5 <strtol+0x19>
        s ++;
c0109da2:	ff 45 08             	incl   0x8(%ebp)
    while (*s == ' ' || *s == '\t') {
c0109da5:	8b 45 08             	mov    0x8(%ebp),%eax
c0109da8:	0f b6 00             	movzbl (%eax),%eax
c0109dab:	3c 20                	cmp    $0x20,%al
c0109dad:	74 f3                	je     c0109da2 <strtol+0x16>
c0109daf:	8b 45 08             	mov    0x8(%ebp),%eax
c0109db2:	0f b6 00             	movzbl (%eax),%eax
c0109db5:	3c 09                	cmp    $0x9,%al
c0109db7:	74 e9                	je     c0109da2 <strtol+0x16>
    }

    // plus/minus sign
    if (*s == '+') {
c0109db9:	8b 45 08             	mov    0x8(%ebp),%eax
c0109dbc:	0f b6 00             	movzbl (%eax),%eax
c0109dbf:	3c 2b                	cmp    $0x2b,%al
c0109dc1:	75 05                	jne    c0109dc8 <strtol+0x3c>
        s ++;
c0109dc3:	ff 45 08             	incl   0x8(%ebp)
c0109dc6:	eb 14                	jmp    c0109ddc <strtol+0x50>
    }
    else if (*s == '-') {
c0109dc8:	8b 45 08             	mov    0x8(%ebp),%eax
c0109dcb:	0f b6 00             	movzbl (%eax),%eax
c0109dce:	3c 2d                	cmp    $0x2d,%al
c0109dd0:	75 0a                	jne    c0109ddc <strtol+0x50>
        s ++, neg = 1;
c0109dd2:	ff 45 08             	incl   0x8(%ebp)
c0109dd5:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%ebp)
    }

    // hex or octal base prefix
    if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) {
c0109ddc:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0109de0:	74 06                	je     c0109de8 <strtol+0x5c>
c0109de2:	83 7d 10 10          	cmpl   $0x10,0x10(%ebp)
c0109de6:	75 22                	jne    c0109e0a <strtol+0x7e>
c0109de8:	8b 45 08             	mov    0x8(%ebp),%eax
c0109deb:	0f b6 00             	movzbl (%eax),%eax
c0109dee:	3c 30                	cmp    $0x30,%al
c0109df0:	75 18                	jne    c0109e0a <strtol+0x7e>
c0109df2:	8b 45 08             	mov    0x8(%ebp),%eax
c0109df5:	40                   	inc    %eax
c0109df6:	0f b6 00             	movzbl (%eax),%eax
c0109df9:	3c 78                	cmp    $0x78,%al
c0109dfb:	75 0d                	jne    c0109e0a <strtol+0x7e>
        s += 2, base = 16;
c0109dfd:	83 45 08 02          	addl   $0x2,0x8(%ebp)
c0109e01:	c7 45 10 10 00 00 00 	movl   $0x10,0x10(%ebp)
c0109e08:	eb 29                	jmp    c0109e33 <strtol+0xa7>
    }
    else if (base == 0 && s[0] == '0') {
c0109e0a:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0109e0e:	75 16                	jne    c0109e26 <strtol+0x9a>
c0109e10:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e13:	0f b6 00             	movzbl (%eax),%eax
c0109e16:	3c 30                	cmp    $0x30,%al
c0109e18:	75 0c                	jne    c0109e26 <strtol+0x9a>
        s ++, base = 8;
c0109e1a:	ff 45 08             	incl   0x8(%ebp)
c0109e1d:	c7 45 10 08 00 00 00 	movl   $0x8,0x10(%ebp)
c0109e24:	eb 0d                	jmp    c0109e33 <strtol+0xa7>
    }
    else if (base == 0) {
c0109e26:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
c0109e2a:	75 07                	jne    c0109e33 <strtol+0xa7>
        base = 10;
c0109e2c:	c7 45 10 0a 00 00 00 	movl   $0xa,0x10(%ebp)

    // digits
    while (1) {
        int dig;

        if (*s >= '0' && *s <= '9') {
c0109e33:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e36:	0f b6 00             	movzbl (%eax),%eax
c0109e39:	3c 2f                	cmp    $0x2f,%al
c0109e3b:	7e 1b                	jle    c0109e58 <strtol+0xcc>
c0109e3d:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e40:	0f b6 00             	movzbl (%eax),%eax
c0109e43:	3c 39                	cmp    $0x39,%al
c0109e45:	7f 11                	jg     c0109e58 <strtol+0xcc>
            dig = *s - '0';
c0109e47:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e4a:	0f b6 00             	movzbl (%eax),%eax
c0109e4d:	0f be c0             	movsbl %al,%eax
c0109e50:	83 e8 30             	sub    $0x30,%eax
c0109e53:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109e56:	eb 48                	jmp    c0109ea0 <strtol+0x114>
        }
        else if (*s >= 'a' && *s <= 'z') {
c0109e58:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e5b:	0f b6 00             	movzbl (%eax),%eax
c0109e5e:	3c 60                	cmp    $0x60,%al
c0109e60:	7e 1b                	jle    c0109e7d <strtol+0xf1>
c0109e62:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e65:	0f b6 00             	movzbl (%eax),%eax
c0109e68:	3c 7a                	cmp    $0x7a,%al
c0109e6a:	7f 11                	jg     c0109e7d <strtol+0xf1>
            dig = *s - 'a' + 10;
c0109e6c:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e6f:	0f b6 00             	movzbl (%eax),%eax
c0109e72:	0f be c0             	movsbl %al,%eax
c0109e75:	83 e8 57             	sub    $0x57,%eax
c0109e78:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109e7b:	eb 23                	jmp    c0109ea0 <strtol+0x114>
        }
        else if (*s >= 'A' && *s <= 'Z') {
c0109e7d:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e80:	0f b6 00             	movzbl (%eax),%eax
c0109e83:	3c 40                	cmp    $0x40,%al
c0109e85:	7e 3b                	jle    c0109ec2 <strtol+0x136>
c0109e87:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e8a:	0f b6 00             	movzbl (%eax),%eax
c0109e8d:	3c 5a                	cmp    $0x5a,%al
c0109e8f:	7f 31                	jg     c0109ec2 <strtol+0x136>
            dig = *s - 'A' + 10;
c0109e91:	8b 45 08             	mov    0x8(%ebp),%eax
c0109e94:	0f b6 00             	movzbl (%eax),%eax
c0109e97:	0f be c0             	movsbl %al,%eax
c0109e9a:	83 e8 37             	sub    $0x37,%eax
c0109e9d:	89 45 f4             	mov    %eax,-0xc(%ebp)
        }
        else {
            break;
        }
        if (dig >= base) {
c0109ea0:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109ea3:	3b 45 10             	cmp    0x10(%ebp),%eax
c0109ea6:	7d 19                	jge    c0109ec1 <strtol+0x135>
            break;
        }
        s ++, val = (val * base) + dig;
c0109ea8:	ff 45 08             	incl   0x8(%ebp)
c0109eab:	8b 45 f8             	mov    -0x8(%ebp),%eax
c0109eae:	0f af 45 10          	imul   0x10(%ebp),%eax
c0109eb2:	89 c2                	mov    %eax,%edx
c0109eb4:	8b 45 f4             	mov    -0xc(%ebp),%eax
c0109eb7:	01 d0                	add    %edx,%eax
c0109eb9:	89 45 f8             	mov    %eax,-0x8(%ebp)
    while (1) {
c0109ebc:	e9 72 ff ff ff       	jmp    c0109e33 <strtol+0xa7>
            break;
c0109ec1:	90                   	nop
        // we don't properly detect overflow!
    }

    if (endptr) {
c0109ec2:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
c0109ec6:	74 08                	je     c0109ed0 <strtol+0x144>
        *endptr = (char *) s;
c0109ec8:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109ecb:	8b 55 08             	mov    0x8(%ebp),%edx
c0109ece:	89 10                	mov    %edx,(%eax)
    }
    return (neg ? -val : val);
c0109ed0:	83 7d fc 00          	cmpl   $0x0,-0x4(%ebp)
c0109ed4:	74 07                	je     c0109edd <strtol+0x151>
c0109ed6:	8b 45 f8             	mov    -0x8(%ebp),%eax
c0109ed9:	f7 d8                	neg    %eax
c0109edb:	eb 03                	jmp    c0109ee0 <strtol+0x154>
c0109edd:	8b 45 f8             	mov    -0x8(%ebp),%eax
}
c0109ee0:	89 ec                	mov    %ebp,%esp
c0109ee2:	5d                   	pop    %ebp
c0109ee3:	c3                   	ret    

c0109ee4 <memset>:
 * @n:      number of bytes to be set to the value
 *
 * The memset() function returns @s.
 * */
void *
memset(void *s, char c, size_t n) {
c0109ee4:	55                   	push   %ebp
c0109ee5:	89 e5                	mov    %esp,%ebp
c0109ee7:	83 ec 28             	sub    $0x28,%esp
c0109eea:	89 7d fc             	mov    %edi,-0x4(%ebp)
c0109eed:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109ef0:	88 45 d8             	mov    %al,-0x28(%ebp)
#ifdef __HAVE_ARCH_MEMSET
    return __memset(s, c, n);
c0109ef3:	0f be 55 d8          	movsbl -0x28(%ebp),%edx
c0109ef7:	8b 45 08             	mov    0x8(%ebp),%eax
c0109efa:	89 45 f8             	mov    %eax,-0x8(%ebp)
c0109efd:	88 55 f7             	mov    %dl,-0x9(%ebp)
c0109f00:	8b 45 10             	mov    0x10(%ebp),%eax
c0109f03:	89 45 f0             	mov    %eax,-0x10(%ebp)
#ifndef __HAVE_ARCH_MEMSET
#define __HAVE_ARCH_MEMSET
static inline void *
__memset(void *s, char c, size_t n) {
    int d0, d1;
    asm volatile (
c0109f06:	8b 4d f0             	mov    -0x10(%ebp),%ecx
c0109f09:	0f b6 45 f7          	movzbl -0x9(%ebp),%eax
c0109f0d:	8b 55 f8             	mov    -0x8(%ebp),%edx
c0109f10:	89 d7                	mov    %edx,%edi
c0109f12:	f3 aa                	rep stos %al,%es:(%edi)
c0109f14:	89 fa                	mov    %edi,%edx
c0109f16:	89 4d ec             	mov    %ecx,-0x14(%ebp)
c0109f19:	89 55 e8             	mov    %edx,-0x18(%ebp)
        "rep; stosb;"
        : "=&c" (d0), "=&D" (d1)
        : "0" (n), "a" (c), "1" (s)
        : "memory");
    return s;
c0109f1c:	8b 45 f8             	mov    -0x8(%ebp),%eax
    while (n -- > 0) {
        *p ++ = c;
    }
    return s;
#endif /* __HAVE_ARCH_MEMSET */
}
c0109f1f:	8b 7d fc             	mov    -0x4(%ebp),%edi
c0109f22:	89 ec                	mov    %ebp,%esp
c0109f24:	5d                   	pop    %ebp
c0109f25:	c3                   	ret    

c0109f26 <memmove>:
 * @n:      number of bytes to copy
 *
 * The memmove() function returns @dst.
 * */
void *
memmove(void *dst, const void *src, size_t n) {
c0109f26:	55                   	push   %ebp
c0109f27:	89 e5                	mov    %esp,%ebp
c0109f29:	57                   	push   %edi
c0109f2a:	56                   	push   %esi
c0109f2b:	53                   	push   %ebx
c0109f2c:	83 ec 30             	sub    $0x30,%esp
c0109f2f:	8b 45 08             	mov    0x8(%ebp),%eax
c0109f32:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0109f35:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109f38:	89 45 ec             	mov    %eax,-0x14(%ebp)
c0109f3b:	8b 45 10             	mov    0x10(%ebp),%eax
c0109f3e:	89 45 e8             	mov    %eax,-0x18(%ebp)

#ifndef __HAVE_ARCH_MEMMOVE
#define __HAVE_ARCH_MEMMOVE
static inline void *
__memmove(void *dst, const void *src, size_t n) {
    if (dst < src) {
c0109f41:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109f44:	3b 45 ec             	cmp    -0x14(%ebp),%eax
c0109f47:	73 42                	jae    c0109f8b <memmove+0x65>
c0109f49:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109f4c:	89 45 e4             	mov    %eax,-0x1c(%ebp)
c0109f4f:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109f52:	89 45 e0             	mov    %eax,-0x20(%ebp)
c0109f55:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109f58:	89 45 dc             	mov    %eax,-0x24(%ebp)
        "andl $3, %%ecx;"
        "jz 1f;"
        "rep; movsb;"
        "1:"
        : "=&c" (d0), "=&D" (d1), "=&S" (d2)
        : "0" (n / 4), "g" (n), "1" (dst), "2" (src)
c0109f5b:	8b 45 dc             	mov    -0x24(%ebp),%eax
c0109f5e:	c1 e8 02             	shr    $0x2,%eax
c0109f61:	89 c1                	mov    %eax,%ecx
    asm volatile (
c0109f63:	8b 55 e4             	mov    -0x1c(%ebp),%edx
c0109f66:	8b 45 e0             	mov    -0x20(%ebp),%eax
c0109f69:	89 d7                	mov    %edx,%edi
c0109f6b:	89 c6                	mov    %eax,%esi
c0109f6d:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
c0109f6f:	8b 4d dc             	mov    -0x24(%ebp),%ecx
c0109f72:	83 e1 03             	and    $0x3,%ecx
c0109f75:	74 02                	je     c0109f79 <memmove+0x53>
c0109f77:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
c0109f79:	89 f0                	mov    %esi,%eax
c0109f7b:	89 fa                	mov    %edi,%edx
c0109f7d:	89 4d d8             	mov    %ecx,-0x28(%ebp)
c0109f80:	89 55 d4             	mov    %edx,-0x2c(%ebp)
c0109f83:	89 45 d0             	mov    %eax,-0x30(%ebp)
        : "memory");
    return dst;
c0109f86:	8b 45 e4             	mov    -0x1c(%ebp),%eax
        return __memcpy(dst, src, n);
c0109f89:	eb 36                	jmp    c0109fc1 <memmove+0x9b>
        : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst)
c0109f8b:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109f8e:	8d 50 ff             	lea    -0x1(%eax),%edx
c0109f91:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109f94:	01 c2                	add    %eax,%edx
c0109f96:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109f99:	8d 48 ff             	lea    -0x1(%eax),%ecx
c0109f9c:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109f9f:	8d 1c 01             	lea    (%ecx,%eax,1),%ebx
    asm volatile (
c0109fa2:	8b 45 e8             	mov    -0x18(%ebp),%eax
c0109fa5:	89 c1                	mov    %eax,%ecx
c0109fa7:	89 d8                	mov    %ebx,%eax
c0109fa9:	89 d6                	mov    %edx,%esi
c0109fab:	89 c7                	mov    %eax,%edi
c0109fad:	fd                   	std    
c0109fae:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
c0109fb0:	fc                   	cld    
c0109fb1:	89 f8                	mov    %edi,%eax
c0109fb3:	89 f2                	mov    %esi,%edx
c0109fb5:	89 4d cc             	mov    %ecx,-0x34(%ebp)
c0109fb8:	89 55 c8             	mov    %edx,-0x38(%ebp)
c0109fbb:	89 45 c4             	mov    %eax,-0x3c(%ebp)
    return dst;
c0109fbe:	8b 45 f0             	mov    -0x10(%ebp),%eax
            *d ++ = *s ++;
        }
    }
    return dst;
#endif /* __HAVE_ARCH_MEMMOVE */
}
c0109fc1:	83 c4 30             	add    $0x30,%esp
c0109fc4:	5b                   	pop    %ebx
c0109fc5:	5e                   	pop    %esi
c0109fc6:	5f                   	pop    %edi
c0109fc7:	5d                   	pop    %ebp
c0109fc8:	c3                   	ret    

c0109fc9 <memcpy>:
 * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed
 * by both @src and @dst, should be at least @n bytes, and should not overlap
 * (for overlapping memory area, memmove is a safer approach).
 * */
void *
memcpy(void *dst, const void *src, size_t n) {
c0109fc9:	55                   	push   %ebp
c0109fca:	89 e5                	mov    %esp,%ebp
c0109fcc:	57                   	push   %edi
c0109fcd:	56                   	push   %esi
c0109fce:	83 ec 20             	sub    $0x20,%esp
c0109fd1:	8b 45 08             	mov    0x8(%ebp),%eax
c0109fd4:	89 45 f4             	mov    %eax,-0xc(%ebp)
c0109fd7:	8b 45 0c             	mov    0xc(%ebp),%eax
c0109fda:	89 45 f0             	mov    %eax,-0x10(%ebp)
c0109fdd:	8b 45 10             	mov    0x10(%ebp),%eax
c0109fe0:	89 45 ec             	mov    %eax,-0x14(%ebp)
        : "0" (n / 4), "g" (n), "1" (dst), "2" (src)
c0109fe3:	8b 45 ec             	mov    -0x14(%ebp),%eax
c0109fe6:	c1 e8 02             	shr    $0x2,%eax
c0109fe9:	89 c1                	mov    %eax,%ecx
    asm volatile (
c0109feb:	8b 55 f4             	mov    -0xc(%ebp),%edx
c0109fee:	8b 45 f0             	mov    -0x10(%ebp),%eax
c0109ff1:	89 d7                	mov    %edx,%edi
c0109ff3:	89 c6                	mov    %eax,%esi
c0109ff5:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
c0109ff7:	8b 4d ec             	mov    -0x14(%ebp),%ecx
c0109ffa:	83 e1 03             	and    $0x3,%ecx
c0109ffd:	74 02                	je     c010a001 <memcpy+0x38>
c0109fff:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
c010a001:	89 f0                	mov    %esi,%eax
c010a003:	89 fa                	mov    %edi,%edx
c010a005:	89 4d e8             	mov    %ecx,-0x18(%ebp)
c010a008:	89 55 e4             	mov    %edx,-0x1c(%ebp)
c010a00b:	89 45 e0             	mov    %eax,-0x20(%ebp)
    return dst;
c010a00e:	8b 45 f4             	mov    -0xc(%ebp),%eax
    while (n -- > 0) {
        *d ++ = *s ++;
    }
    return dst;
#endif /* __HAVE_ARCH_MEMCPY */
}
c010a011:	83 c4 20             	add    $0x20,%esp
c010a014:	5e                   	pop    %esi
c010a015:	5f                   	pop    %edi
c010a016:	5d                   	pop    %ebp
c010a017:	c3                   	ret    

c010a018 <memcmp>:
 *   match in both memory blocks has a greater value in @v1 than in @v2
 *   as if evaluated as unsigned char values;
 * - And a value less than zero indicates the opposite.
 * */
int
memcmp(const void *v1, const void *v2, size_t n) {
c010a018:	55                   	push   %ebp
c010a019:	89 e5                	mov    %esp,%ebp
c010a01b:	83 ec 10             	sub    $0x10,%esp
    const char *s1 = (const char *)v1;
c010a01e:	8b 45 08             	mov    0x8(%ebp),%eax
c010a021:	89 45 fc             	mov    %eax,-0x4(%ebp)
    const char *s2 = (const char *)v2;
c010a024:	8b 45 0c             	mov    0xc(%ebp),%eax
c010a027:	89 45 f8             	mov    %eax,-0x8(%ebp)
    while (n -- > 0) {
c010a02a:	eb 2e                	jmp    c010a05a <memcmp+0x42>
        if (*s1 != *s2) {
c010a02c:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010a02f:	0f b6 10             	movzbl (%eax),%edx
c010a032:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010a035:	0f b6 00             	movzbl (%eax),%eax
c010a038:	38 c2                	cmp    %al,%dl
c010a03a:	74 18                	je     c010a054 <memcmp+0x3c>
            return (int)((unsigned char)*s1 - (unsigned char)*s2);
c010a03c:	8b 45 fc             	mov    -0x4(%ebp),%eax
c010a03f:	0f b6 00             	movzbl (%eax),%eax
c010a042:	0f b6 d0             	movzbl %al,%edx
c010a045:	8b 45 f8             	mov    -0x8(%ebp),%eax
c010a048:	0f b6 00             	movzbl (%eax),%eax
c010a04b:	0f b6 c8             	movzbl %al,%ecx
c010a04e:	89 d0                	mov    %edx,%eax
c010a050:	29 c8                	sub    %ecx,%eax
c010a052:	eb 18                	jmp    c010a06c <memcmp+0x54>
        }
        s1 ++, s2 ++;
c010a054:	ff 45 fc             	incl   -0x4(%ebp)
c010a057:	ff 45 f8             	incl   -0x8(%ebp)
    while (n -- > 0) {
c010a05a:	8b 45 10             	mov    0x10(%ebp),%eax
c010a05d:	8d 50 ff             	lea    -0x1(%eax),%edx
c010a060:	89 55 10             	mov    %edx,0x10(%ebp)
c010a063:	85 c0                	test   %eax,%eax
c010a065:	75 c5                	jne    c010a02c <memcmp+0x14>
    }
    return 0;
c010a067:	b8 00 00 00 00       	mov    $0x0,%eax
}
c010a06c:	89 ec                	mov    %ebp,%esp
c010a06e:	5d                   	pop    %ebp
c010a06f:	c3                   	ret    
